简单的4行C程序,只有大量的malloc与Valgrind的段错误

时间:2014-07-02 10:39:59

标签: c segmentation-fault malloc valgrind

如果在没有valgrind的情况下运行以下内容,我就不会遇到段错误。当它与valgrind一起运行时,我做到了。它似乎是malloc大小的结果,因为如果我将它大约1/4那么大,那就不会发生。

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

int main()
{
    float *a = malloc(400000000 * sizeof(float));
    a[5] = 3.0;
    printf("%f\n", a[5]);
    free(a);
}

这是valgrind的输出

==31972== Memcheck, a memory error detector
==31972== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==31972== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info
==31972== Command: ./seg
==31972== 
==31972== Invalid write of size 4
==31972==    at 0x80484A5: main (seg.c:8)
==31972==  Address 0x5f5e0ffc is not stack'd, malloc'd or (recently) free'd
==31972== 
==31972== 
==31972== Process terminating with default action of signal 11 (SIGSEGV)
==31972==  Access not within mapped region at address 0x5F5E0FFC
==31972==    at 0x80484A5: main (seg.c:8)
==31972==  If you believe this happened as a result of a stack
==31972==  overflow in your program's main thread (unlikely but
==31972==  possible), you can try to increase the size of the
==31972==  main thread stack using the --main-stacksize= flag.
==31972==  The main thread stack size used in this run was 8388608.
==31972== 
==31972== HEAP SUMMARY:
==31972==     in use at exit: 0 bytes in 0 blocks
==31972==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==31972== 
==31972== All heap blocks were freed -- no leaks are possible
==31972== 
==31972== For counts of detected and suppressed errors, rerun with: -v
==31972== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault

如果我做的数学正确,那就是大约1.5 GB的内存。

如果我执行bash命令free -m运行它,看起来我有大约2 GB的免费ram。也许这就是它的关闭?

有什么想法?可能这意味着我'关闭'到segfaulting 没有 valgrind,如果我使用了更多的内存?

1 个答案:

答案 0 :(得分:2)

malloc()尝试分配连续的内存块。您的系统总共可能有2GB空闲,但可能在单个块中不存在。这就是问题所在。我敢打赌,如果你真的检查过,你会发现内存分配失败了。

在这种情况下,您尝试访问第2行的NULL指针。

根据malloc的{​​{3}}

  

默认情况下,Linux遵循乐观的内存分配策略。   这意味着当malloc()返回非NULL时,无法保证   内存确实可用。如果事实证明了   系统内存不足,一个或多个进程将被杀死   OOM杀手。有关更多信息,请参阅的说明   proc(5)中的/ proc / sys / vm / overcommit_memory和/ proc / sys / vm / oom_adj,   和Linux内核源文件   文档/ VM /过量使用计费。

所以我猜那里还有一个不可预测的因素。