为什么malloc()初始化新分配的内存块的值?

时间:2013-07-14 11:46:56

标签: c dynamic-allocation

我开始学习C中的动态内存分配,到目前为止,我已经阅读过malloc()函数,并没有初始化新分配的块的值。

在较新版本的C中是否已更改? C99和C11?

我正在使用Xcode执行以下操作,所有值都使用0初始化。

double *p = (double *) malloc(5 * sizeof(double));

printf("Address of p0 = %p | Valoe of p0 = %f\n", p, *p);
printf("Address of p1 = %p | Valoe of p1 = %f\n", p+1, *(p+1));
printf("Address of p2 = %p | Valoe of p2 = %f\n", p+2, *(p+2));
printf("Address of p3 = %p | Valoe of p3 = %f\n", p+3, *(p+3));
printf("Address of p4 = %p | Valoe of p4 = %f\n", p+4, *(p+4));

我认为这只适用于函数calloc()。

6 个答案:

答案 0 :(得分:9)

似乎是实现定义的行为。在Visual Studio 2012,C编译器上,我看不到这样的初始化。

更重要的是,请阅读此问题中所选答案的“捕获”:

Why does malloc initialize the values to 0 in gcc?

说,由于安全原因,操作系统可能会“给你”归零值。看起来,这是一个实现定义的行为。

一条建议:它不是标准行为,并且破坏了代码的可移植性。确保初始化值而不依赖于OS提供的数据。

答案 1 :(得分:4)

你很幸运(如果你相信的话,还是不走运)。 Malloc内部没有这样的东西(但它要求操作系统获得分配,我不知道操作系统的行为)。当你反复malloc某些区域时,可能会有一些性能下降。那些零来自未受影响的森林。

首先是malloc,然后初始化为随机数/字符然后重复多次,然后你将在malloc之后开始获得非零元素。

不要忘记随机大小的malloc之间的free()。​​

答案 2 :(得分:3)

你以为“我得0”总是意味着“价值0故意放在这里”,情况并非如此。

您的代码中没有初始化。

答案 3 :(得分:2)

首先,malloc没有按照标准初始化返回的内存块(这没有改变)这一事实并不意味着一定不能这样做,而是不需要这样做

malloc无论如何都允许初始化内存块。甚至可以想象(但不明智的)调试构建对所有分配的块进行零初始化。然而,更好的解决方案是用可识别的模式填充它们。

最重要的是,从操作系统获得的新页面始终归零。这样做是出于安全原因,没有例外(某些嵌入式系统可能是罕见的例外,但没有"主流"系统将为您提供未初始化的页面)。因此,在某些情况下,内存可能是零初始化的,但您无法知道它是malloc这样做还是其他人。

答案 4 :(得分:0)

未定义已分配块的内容,因此它是特定于实现的。

某些实现(如您正在使用的那个)将其设置为零,其他实现为0xdeadbeef或其他一些幻数(msvc ++编译的malloc用0xCC填充但不是所有内容。)

它是特定于实现的,因此未定义,依赖它。

并且永远不要仅仅因为它是危险的而在内存中重新分配内存。

答案 5 :(得分:0)

在多用户操作系统中,当操作系统将内存提供给进程时,操作系统通常会清除内存,以便它不会显示以前来自其他进程的数据。 (当然,系统不必将此内存归零;为了保护隐私,它只需将内存设置为任何不包含私有数据的值。通常使用零。)

这意味着当malloc返回从操作系统中新获得的内存时,当内存池malloc以前不足以满足您的请求时,会发生这种情况,该内存将包含零。但是,当malloc返回您的进程以前使用的内存时,它可能包含其他数据。 (其中一些数据可能来自程序中通常不可见的部分,例如C运行时初始化代码或动态加载程序和链接器。)

由于此行为是您的操作系统而非C规范的结果,因此仅在基于C规范的软件时,您可能不会依赖它。如果您无法保证会发生此行为,则必须编写软件,就像每个malloc都可以返回未初始化的数据一样,即使经验或考试经常显示也是如此。