【问题标题】:possible reasons why C program malloc assignment returns NULL?C程序malloc赋值返回NULL的可能原因?
【发布时间】:2011-12-07 17:25:36
【问题描述】:

我在 64 位 Linux centos 5.7 上使用 gcc4.4.4 和 gdb,编译为 ansi C。我不确定为什么我的代码在下面的 PDF == NULL 测试为 true,并调用 exit(2)。

void func(...)
...
double *PDF;
...
PDF = malloc( sizeof(double) * 1 );
if (PDF == NULL) {
    exit(2); 
}

使用free -m,我在程序启动前观察:

             total       used       free     shared    buffers     cached
Mem:          2001       1955         46          0         71        975
-/+ buffers/cache:        907       1094
Swap:         4008        688       3319

当程序位于出口时(2);一行代码,free -m 内容为:

             total       used       free     shared    buffers     cached
Mem:          2001       1970         31          0         72        976
-/+ buffers/cache:        921       1080
Swap:         4008        688       3319

在这两种情况下,缓存行、空闲列中都有大量可用内存(当然足够一个字节)。

PDF 变为 NULL 的其他可能原因是什么?哪些编码错误会导致这种情况?

如果这很重要,上周我一直在使用 gdb,使用“q”然后“y”退出程序,而不是让它完成(计算所有 malloc 内存将被程序终止释放不需要执行 free() 代码)。

【问题讨论】:

  • 我们能否看到重现该问题的SSCCE 示例(main()、包含和 gcc 标志)?

标签: c


【解决方案1】:

如果您在某处写入超出缓冲区的边界,则可能已损坏堆,在这种情况下,所有赌注都已关闭。

我建议使用例如Valgrind 来检查你没有做过这样的事情。

【讨论】:

  • 甚至不适用于分配一个字节(上面更新的问题)。
  • @ggkmath:没关系;如果堆已损坏,则堆已损坏。
  • 确实,更有理由相信堆已损坏。
  • 在此之前我在堆上做了很多事情,所以这可能是原因。有什么好的方法可以使用 gdb 进行调试吗?
  • @ggkmath:使用合适的内存调试器会容易得多,比如 Valgrind。它旨在准确诊断此类问题。
【解决方案2】:

malloc 在调用进程无法分配更多内存时返回 NULL,可能是因为 mmap 系统调用失败,因为您达到了某些限制,例如由 setrlimit 设置的限制

即使某些内存可供其他进程使用,单个进程也可能达到其极限。

您可以使用strace 跟踪系统调用并找出失败的系统调用。

并确保使用gcc -Wall -g 进行编译(并使用调试器gdb)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-14
    • 1970-01-01
    • 1970-01-01
    • 2013-01-06
    • 2016-05-11
    • 2015-06-14
    • 2016-05-24
    相关资源
    最近更新 更多