c - 为什么 malloc 将 gcc 中的值初始化为 0?

可能平台不同,但是

当我使用 gcc 编译并运行下面的代码时,我每次在我的 ubuntu 11.10 中都得到 0。

#include <stdio.h>
#include <stdlib.h>

int main()
{
    double *a = malloc(sizeof(double)*100)
    printf("%f", *a);
}

为什么即使有calloc,malloc的行为也会如此?

这是否意味着即使您有时不希望将值初始化为 0 也会产生不必要的性能开销?


编辑:哦,我之前的例子不是初始化,而是碰巧使用了“新鲜” 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 时有安全原因! (从来没有想过)。当然在分配新 block 或大块时它必须初始化为零。

最佳答案

简答:

不是,只是在你的情况下它恰好为零。
(你的测试用例也没有显示数据为零。它只显示一个元素是否为零。)


长答案:

当你调用 malloc() 时,会发生以下两种情况之一:

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

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

在第二种情况下,内存将来自操作系统。当程序内存不足或请求非常大的分配时,就会发生这种情况。 (就像你的例子一样)

这里有一个问题:出于安全原因,来自操作系统的内存将被清零。*

当操作系统为您提供内存时,它可能已从不同的进程中释放出来。因此,该内存可能包含敏感信息,例如密码。因此,为了防止您读取此类数据,操作系统会在将其提供给您之前将其归零。

*我注意到 C 标准对此只字未提。这严格来说是一种操作系统行为。因此,在不考虑安全性的系统上,这种归零可能存在也可能不存在。


为了提供更多的性能背景:

作为@R。在评论中提到,这个归零就是为什么你应该总是 use calloc() instead of malloc() + memset() . calloc() 可以利用这一事实来避免单独的 memset()


另一方面,这种归零有时是性能瓶颈。在一些数值应用程序(例如 out-of-place FFT )中,您需要分配大量的暂存内存。用它来执行任何算法,然后释放它。

在这些情况下,归零是不必要的,相当于纯粹的开销。

我见过的最极端的例子是使用 48 GB 暂存缓冲区进行 70 秒操作的 20 秒归零开销。 (大约 30% 的开销。) (当然:机器确实缺少内存带宽。)

显而易见的解决方案是简单地手动重用内存。但这通常需要突破已建立的接口(interface)。 (特别是如果它是库例程的一部分)

https://stackoverflow.com/questions/8029584/

相关文章:

python - Pandas 中的 join 和 merge 有什么区别?

linux - 如何 cat <> 包含代码的文件?

linux - 使用 bash 脚本自动化远程登录 session

regex - 更改文件夹中的所有匹配项

python - 如何通过 Django 发送电子邮件?

linux - bash - 如何将结果从 which 命令传送到 cd

linux - 在 Bash 脚本中引发错误

python - 列表列表到 numpy 数组中

python - 什么是好的速率限制算法?

python - 使用 csv 模块从 csv 文件中读取特定列?