2013-07-14 64 views
3

我开始学习C语言中的动态内存分配,到目前为止我读过的malloc()函数不会初始化新分配的块的值。为什么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这是真实的()。

+2

我认为这是因为您配合的内存之前未被其他非零变量使用。你不能确定它总是如此。 – lulyon

+1

似乎是未定义的行为。再重复几次,并检查是否仍然得到0. –

+0

只要使用'calloc',如果你想要一个零初始化区域。 –

回答

9

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

更重要的是,阅读所选答案的“捕获”这样一个问题:

Why does malloc initialize the values to 0 in gcc?

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

建议:它不是标准的行为并且破坏了代码的可移植性。确保初始化值而不依赖于操作系统给出的数据。

+0

太棒了!非常感谢 –

+0

@ItaloGrossi没有问题。快乐的编码 –

4

你很幸运(或者如果你信任这个,就不吉利)。 Malloc在内部没有这样的东西(但它要求操作系统获得分配,我不知道操作系统的行为)。那么当你反复malloc某些区域时,可能会有一些性能下降。那些零是来自未触动过的森林。

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

不要忘记在随机大小的malloc之间释放()。

+0

嗨,侯赛因非常感谢你的回复。 我已经完成了你的建议。 1 - 使用malloc分配5个int值的内存。 2 - 随机初始化使用srand()函数和随机() 3的5个整数 - 印刷 4的值 - 使用免费() 5 - 分配给5 INT新的存储值 6 - 再次打印的值 对于令人惊讶的是,第6步打印的值是第3步的旧值。 所以你是对的......这次新分配的内存没有用零初始化。相反,它只是从步骤2开始的随机值。 –

+0

但是,您可能需要扫描整个编译器的工作区域以确保获得非零值:)这可能需要很多malloc。 :) 玩的开心。 –

2

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

这是非常好的允许malloc无论如何初始化内存块。甚至可以想象(但不明智的是)调试版本将所有分配的块初始化为零。然而,更好的解决方案是填充可识别的图案。

最重要的是,从操作系统获取的新页面始终为零。这是出于安全原因,没有例外(一些嵌入式系统可能是罕见的例外,但没有“主流”系统会给你一个未初始化的页面)。因此,在某些情况下,内存可能会被初始化为零,但您无法知道是否是malloc这样做或其他人。

3

你已经假设“我得到0”总是意味着“值0被故意放在这里”,事实并非如此。

代码中没有初始化。

0

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

某些实现(如你正在使用的那个)将其设置为零,其他实现为0xdeadbeef或其他一些幻数(msvC++编译的malloc用0xCC填充,但不是全部)。

它是实现特定的,因此不确定,做而不是取决于它。

并且不要仅仅因为危险而重新分配内存中的内存。

0

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

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

由于此行为是您的操作系统而不是C规范,在基于C规范的软件时,您可能不会依赖它。如果您无法确定会发生此行为,则必须编写软件,就好像每个malloc都可以返回未初始化的数据,即使经验或检查经常显示其他情况。

相关问题