为什么 malloc 将 gcc 中的值初始化为 0? [英] Why does malloc initialize the values to 0 in gcc?
问题描述
可能平台不同,但是
当我使用 gcc 编译并运行下面的代码时,我每次在我的 ubuntu 11.10 中都得到 0.
when I compile using gcc and run the code below, I get 0 every time in my ubuntu 11.10.
#include <stdio.h>
#include <stdlib.h>
int main()
{
double *a = malloc(sizeof(double)*100)
printf("%f", *a);
}
为什么即使有calloc,malloc的行为也会如此?
Why do malloc behave like this even though there is calloc?
这是否意味着即使您有时不希望将值初始化为 0 也会产生不必要的性能开销?
Doesn't it mean that there is an unwanted performance overhead just to initialize the values to 0 even if you don't want it to be sometimes?
哦,我之前的例子不是初始化,而是碰巧使用了新鲜".块.
Oh, my previous example was not initiazling, but happened to use "fresh" block.
我正在寻找的是为什么它在分配一个大块时初始化它:
What I precisely was looking for was why it initializes it when it allocates a large block:
int main()
{
int *a = malloc(sizeof(int)*200000);
a[10] = 3;
printf("%d", *(a+10));
free(a);
a = malloc(sizeof(double)*200000);
printf("%d", *(a+10));
}
OUTPUT: 3
0 (initialized)
但是感谢您指出 malloc 时有安全原因!(从来没有想过).当然在分配新块或大块时它必须初始化为零.
But thanks for pointing out that there is a SECURITY reason when mallocing! (Never thought about it). Sure it has to initialize to zero when allocating fresh block, or the large block.
推荐答案
简答:
不是,只是在你的情况下它恰好为零.
(你的测试用例也没有显示数据为零.它只显示一个元素是否为零.)
It doesn't, it just happens to be zero in your case.
(Also your test case doesn't show that the data is zero. It only shows if one element is zero.)
长答案:
当你调用 malloc()
时,会发生以下两种情况之一:
When you call malloc()
, one of two things will happen:
- 它会回收之前从同一进程分配和释放的内存.
- 它向操作系统请求新页面.
在第一种情况下,内存将包含先前分配的剩余数据.所以不会是零.这是执行小分配时的常见情况.
In the first case, the memory will contain data leftover from previous allocations. So it won't be zero. This is the usual case when performing small allocations.
在第二种情况下,内存将来自操作系统.当程序内存不足或请求非常大的分配时,就会发生这种情况.(就像你的例子一样)
In the second case, the memory will be from the OS. This happens when the program runs out of memory - or when you are requesting a very large allocation. (as is the case in your example)
这里有一个问题:出于安全原因,来自操作系统的内存将被清零.*
Here's the catch: Memory coming from the OS will be zeroed for security reasons.*
当操作系统为您提供内存时,它可能已从不同的进程中释放出来.因此,该内存可能包含敏感信息,例如密码.因此,为了防止您读取此类数据,操作系统会在将其提供给您之前将其归零.
When the OS gives you memory, it could have been freed from a different process. So that memory could contain sensitive information such as a password. So to prevent you reading such data, the OS will zero it before it gives it to you.
*我注意到 C 标准对此只字未提.这严格来说是一种操作系统行为.因此,在不考虑安全性的系统上,这种归零可能存在也可能不存在.
为了提供更多的性能背景:
作为@R.在评论中提到,这种归零就是为什么你应该总是 使用 calloc()
而不是 malloc()
+ memset()
.calloc()
可以利用这一事实来避免单独的 memset()
.
As @R. mentions in the comments, this zeroing is why you should always use calloc()
instead of malloc()
+ memset()
. calloc()
can take advantage of this fact to avoid a separate memset()
.
另一方面,这种归零有时是性能瓶颈.在某些数值应用中(例如 out-of-place FFT),您需要分配一个大量的暂存内存.用它来执行任何算法,然后释放它.
On the other hand, this zeroing is sometimes a performance bottleneck. In some numerical applications (such as the out-of-place FFT), you need to allocate a huge chunk of scratch memory. Use it to perform whatever algorithm, then free it.
在这些情况下,归零是不必要的,相当于纯粹的开销.
我见过的最极端的例子是使用 48 GB 暂存缓冲区进行 70 秒操作的 20 秒归零开销.(大约 30% 的开销.)(当然:机器确实缺少内存带宽.)
The most extreme example I've seen is a 20-second zeroing overhead for a 70-second operation with a 48 GB scratch buffer. (Roughly 30% overhead.) (Granted: the machine did have a lack of memory bandwidth.)
显而易见的解决方案是简单地手动重用内存.但这通常需要突破已建立的接口.(特别是如果它是库例程的一部分)
The obvious solution is to simply reuse the memory manually. But that often requires breaking through established interfaces. (especially if it's part of a library routine)
这篇关于为什么 malloc 将 gcc 中的值初始化为 0?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!