为什么malloc在gcc中将值初始化为0?
平台之间可能有所不同,但是
当我使用gcc编译并运行下面的代码时,每次在ubuntu 11.10中获得0。
#include <stdio.h>#include <stdlib.h>
int main()
{
double *a = (double*) malloc(sizeof(double)*100)
printf("%f", *a);
}
为什么即使有calloc,malloc的行为也是如此?
难道就意味着即使您不希望有时将值初始化为0,也会有不必要的性能开销吗?
编辑:哦,我以前的示例不是初始化,而是碰巧使用“新鲜”块。
我恰恰在寻找的是为什么它在分配一个大块时将其初始化:
int main(){
int *a = (int*) malloc(sizeof(int)*200000);
a[10] = 3;
printf("%d", *(a+10));
free(a);
a = (double*) malloc(sizeof(double)*200000);
printf("%d", *(a+10));
}
OUTPUT: 3
0 (initialized)
但是,感谢您指出进行分配时存在安全原因!(从来没有想过)。确保在分配新鲜块或大块时必须将其初始化为零。
回答:
并非如此,在您的情况下恰好为零。
(此外,您的测试用例不会显示数据为零。仅显示一个元素为零的情况。)
当您致电时malloc()
,将发生以下两种情况之一:
- 它回收先前分配的内存并从同一进程中释放出来。
- 它从操作系统请求新页面。
在第一种情况下,内存将包含以前分配剩余的数据。因此它不会为零。这是执行小分配时的通常情况。
在第二种情况下,内存将来自操作系统。当程序内存不足时或在请求大量分配时,会发生这种情况。(例如您的示例)
问题在于: *
当操作系统为您提供内存时,它可能已从其他进程中释放出来。这样,内存可以包含敏感信息,例如密码。因此,为防止您读取此类数据,操作系统会在将数据提供给您之前将其清零。
*我注意到C标准对此没有说明。严格来说,这是一种操作系统行为。因此,在不考虑安全性的系统上,可能会或可能不会出现这种调零。
作为@R。在评论中提到,此归零是为什么您应始终使用calloc()
而不是malloc()
+的原因memset()
。calloc()
可以利用这个事实来避免单独使用memset()
。
另一方面,这种归零有时是性能瓶颈。在某些数字应用程序中(例如,不适当的FFT),您需要分配大量的暂存存储器。使用它执行任何算法,然后释放它。
在这些情况下,归零是不必要的,并且完全是开销。
我看到的最极端的示例是使用48 GB暂存缓冲区进行70秒的操作需要20秒的清零开销。(大约30%的开销。) (保证:机器确实没有内存带宽。)
显而易见的解决方案是简单地手动重用内存。但这通常需要突破已建立的接口。(特别是如果它是库例程的一部分)
以上是 为什么malloc在gcc中将值初始化为0? 的全部内容, 来源链接: utcz.com/qa/416076.html