简体   繁体   English

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

[英]simple 4-line C program with massive malloc only segfaults with Valgrind

When the following is run without valgrind, I don't get a segfault. 如果在没有valgrind的情况下运行以下内容,我就不会遇到段错误。 When it's run with valgrind, I do. 当它与valgrind一起运行时,我做到了。 It seems to be a result of the size of the malloc, because if I make it about 1/4 that size, it doesn't happen. 它似乎是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);
}

Here's the output from valgrind 这是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

If I did the math right, that's about 1.5 GB of memory. 如果我做了正确的数学计算,那就是大约1.5 GB的内存。

If I do the bash command free -m while not running it, it looks like I have about 2 GB of free ram. 如果我执行bash命令free -m 而不运行它,看起来我有大约2 GB的免费ram。 Perhaps that's cutting it close? 也许那就是它的关闭?

Any thoughts? 有什么想法吗? Might it mean that I'm 'close' to segfaulting without valgrind, if I malloced even more memory? 可能这意味着如果我没有使用 valgrind,我会“接近” segfaulting,如果我更多地记录了内存?

malloc() attempts to allocate a contiguous block of memory. malloc()尝试分配连续的内存块。 You might have 2GB free in your system in total , but chances are it does not exist in a single chunk. 您的系统中可能总共有2GB可用空间,但可能在一个块中不存在。 And that is the problem. 这就是问题所在。 I bet that if you actually checked, you would see that the memory allocation failed. 我敢打赌,如果你真的检查过,你会发现内存分配失败了。

In that case you are attempting to access a NULL pointer on line 2. 在这种情况下,您尝试访问第2行上的NULL指针。

According to the documentation for malloc 根据malloc文档

By default, Linux follows an optimistic memory allocation strategy. 默认情况下,Linux遵循乐观的内存分配策略。 This means that when malloc() returns non-NULL there is no guarantee that the memory really is available. 这意味着当malloc()返回非NULL时,无法保证内存确实可用。 In case it turns out that the system is out of memory, one or more processes will be killed by the OOM killer. 如果事实证明系统内存不足,那么一个或多个进程将被OOM杀手杀死。 For more information, see the description of /proc/sys/vm/overcommit_memory and /proc/sys/vm/oom_adj in proc(5), and the Linux kernel source file Documentation/vm/overcommit-accounting. 有关更多信息,请参阅proc(5)中的/ proc / sys / vm / overcommit_memory和/ proc / sys / vm / oom_adj以及Linux内核源文件Documentation / vm / overcommit-accounting中的说明。

so I guess there is an additional element of unpredictability there. 所以我猜那里还有一个不可预测的因素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM