为什么 malloc 在 gcc 中将值初始化为 0? [英] Why does malloc initialize the values to 0 in gcc?

查看:49
本文介绍了为什么 malloc 在 gcc 中将值初始化为 0?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

也许平台不同,但是

当我使用 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 = (double*) 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 = (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)

但是感谢您指出mallocing时有一个安全原因!(从来没想过).当然在分配新块或大块时它必须初始化为零.

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:

  1. 它回收先前从同一进程分配和释放的内存.
  2. 它从操作系统请求新页面.

在第一种情况下,内存将包含以前分配的剩余数据.所以不会为零.这是执行小型分配时的常见情况.

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.

在这些情况下,归零是不必要的,而且是纯粹的开销.

我见过的最极端的例子是 20 秒清零开销,用于 48 GB 暂存缓冲区的 70 秒操作.(大约 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆