马洛克的优势是什么?



为某些数据分配内存有什么好处。相反,我们可以使用它们的数组。

喜欢

 int *lis;
 lis = (int*) malloc ( sizeof( int ) * n );
 /* Initialize LIS values for all indexes */
 for ( i = 0; i < n; i++ )
 lis[i] = 1;

我们本可以使用普通数组。

好吧,我不明白malloc是如何工作的,实际上是做什么的。因此,解释它们对我更有益。

假设我们在上面的代码中仅用n替换sizeof(int) * n,然后尝试存储整数值,我可能会面临什么问题?有没有办法直接从内存分配的空间打印存储在变量中的值,例如这里lis

您的问题似乎更愿意将动态分配的 C 样式数组与可变长度数组进行比较,这意味着这可能是您正在寻找的: 为什么可变长度数组不是C++标准的一部分?

然而,c++ 标签产生了最终的答案:改用std::vector对象。

只要可能,请避免动态分配和负责丑陋的内存管理~>尝试利用具有自动存储持续时间的对象。另一个有趣的读物可能是:理解术语和概念的含义 - RAII(资源获取是初始化)


"假设我们将sizeof(int) * n替换为上述代码中的n,然后尝试存储整数值,我可能会面临什么问题?"
- 如果您仍然认为n是可以存储在此数组中的整数数量,则很可能会遇到未定义的行为

更根本的是,我认为,除了堆栈与堆和变量与常量问题(以及您不应该在C++中使用malloc()的事实之外),当函数退出时,局部数组将不复存在。如果返回指向它的指针,则一旦调用方收到该指针,该指针将毫无用处,而使用 malloc()new 动态分配的内存仍然有效。例如,您无法使用本地数组实现像strdup()这样的函数,也无法明智地实现链接表示列表或树。

答案很简单。本地1 数组在您的堆栈上分配,这是为您的程序预先分配的小内存。超过几千个数据,你无法在一个堆栈上做很多事情。对于更多的数据,您需要从堆栈中分配内存。

这就是malloc所做的。

malloc分配了一段记忆,就像你问它一样大。它返回一个指向该内存开头的指针,该指针可以类似于数组处理。如果写入超出该内存的大小,则结果是未定义的行为。这意味着一切可以正常工作,或者您的计算机可能会爆炸。最有可能的是,您会收到分段错误错误。

内存中读取值(例如用于打印)与从数组中读取值相同。例如printf("%d", list[5]); .

在 C99 之前(我知道这个问题被标记为C++,但可能您正在学习 C 编译的 C++),还有另一个原因。你不可能在堆栈上有一个可变长度的数组。(即使是现在,堆栈上的可变长度数组也不是那么有用,因为堆栈很小)。这就是为什么对于可变内存量,您需要 malloc 函数来分配尽可能大的内存,其大小在运行时确定。

局部

数组或任何局部变量之间的另一个重要区别是对象的生命周期。局部变量在其作用域完成后立即无法访问。 malloc ed 对象一直存在到它们被free d。这在几乎所有不是数组的数据结构中都是必不可少的,例如链表、二叉搜索树(和变体)、(大多数)堆等。

malloc ed 对象的一个例子是 FILE s。一旦你调用 fopen ,保存与打开的文件相关的数据的结构就会使用 malloc 动态分配,并以指针 (FILE * ) 的形式返回。


1 注意:非本地数组(全局或静态)是在执行之前分配的,因此它们不能真正在运行时确定长度。

我假设你在问 c maloc()的目的是什么:假设您想从用户那里获取输入,现在分配该大小的数组:

int n;
scanf("%d",&n);
int arr[n];

这将失败,因为 n 在编译时不可用。来malloc()你可以写:

int n;
scanf("%d",&n);
int* arr = malloc(sizeof(int)*n);

实际上malloc()堆区域中动态分配内存

一些较旧的编程环境根本不提供malloc或任何等效的功能。 如果你需要动态内存分配,你必须在巨大的静态数组之上自己编码。 这有几个缺点:

  • 静态数组大小对程序在任何时候可以处理的数据量设置了硬性上限,而无需重新编译。 如果您曾经尝试在TeX中做一些复杂的事情并收到"容量超出,抱歉"消息,这就是原因。
  • 操作系统(就像它一样)必须一次性为静态数组保留空间,无论它是否全部使用。 这种现象导致了"过度使用",其中操作系统假已经分配了您可能想要的所有内存,但如果您实际尝试使用超过可用内存的内存,则会终止您的进程。为什么有人想要这样?然而,它在90年代中期的商业Unix中被大肆宣传为一项功能,因为这意味着巨大的FORTRAN模拟可能需要比你笨拙的小Sun工作站更多的内存,可以在小实例上进行测试,没有麻烦。 (大概你会在某个实际上有足够的内存来应对的 Cray 上运行实例。
  • 动态内存分配器很难很好地实现。 看看 jemalloc 纸,看看它有多毛茸茸的。 (如果你想要自动垃圾回收,它会变得更加复杂。这正是您希望大师为了每个人的利益而编写一次代码的那种事情。

所以现在即使是相当准系统的嵌入式环境也会给你某种动态分配器。

然而,尝试没有是很好的心理纪律。 过度使用动态内存会导致效率低下,这种效率通常很难在事后消除,因为它已经融入了架构中。 如果手头的任务似乎不需要动态分配,也许不需要。

但是,在真正应该使用时不使用动态内存分配可能会导致其自身的问题,例如对字符串的长度施加硬上限,或者将不可重入性烘焙到您的 API 中(将gethostbynamegetaddrinfo 进行比较)。

所以你必须仔细考虑一下。

我们本可以使用一个普通数组

在C++(至少今年),数组具有静态大小;因此从运行时值创建一个数组:

int lis[n];

是不允许的。一些编译器允许将其作为非标准扩展,并且将于明年成为标准;但是,就目前而言,如果我们想要一个动态大小的数组,我们必须动态分配它。

在C中,这意味着弄乱malloc;但你问的是C++,所以你想要

std::vector<int> lis(n, 1);

分配大小n数组,其中包含初始化为 1 的int值。

(如果你愿意,你可以用new int[n]分配数组,并记得在完成后用delete [] lis释放它,如果抛出异常,要格外小心不要泄漏;但生命太短了,不能胡说八道。

好吧,我不明白malloc是如何工作的,实际上是做什么的。因此,解释它们对我更有益。

malloc C 语言

new C 语言C++从"免费存储"中分配持久内存。与局部变量的内存不同,当变量超出范围时会自动释放,它会一直存在,直到您显式释放它(在 C 中free,在 C++ 中delete)。如果您需要数组在当前函数调用之后存活,这是必需的。如果数组非常大,这也是一个好主意:局部变量(通常)存储在堆栈上,大小有限。如果溢出,程序将崩溃或出错。(而且,在当前的标准C++中,如果大小不是编译时常量,则有必要这样做)。

假设我们将sizeof(int) * n替换为上述代码中的n,然后尝试存储整数值,我可能会面临什么问题?

您没有为n整数分配足够的空间;因此,假设您拥有的空间的代码将尝试访问超出分配空间末尾的内存。这将导致未定义的行为;如果幸运的话会崩溃,如果运气不好,数据会损坏。

有没有办法直接从内存分配的空间打印存储在变量中的值,例如这里lis

你的意思是这样?

for (i = 0; i < len; ++i) std::cout << lis[i] << 'n';

相关内容

  • 没有找到相关文章

最新更新