c - malloc 中的信号 11 SIGSEGV?

标签 c memory-management segmentation-fault

我通常喜欢解释清楚的问题和答案。但在这种情况下我真的无法提供更多线索。

问题是:为什么 malloc() 给我 SIGSEGV?下面的调试显示程序没有时间测试返回的指针是否为 NULL 并退出。程序退出 INSIDE MALLOC!

我假设 glibc 中的 malloc 没问题。我有一个 debian/linux wheezy 系统,已更新,位于旧的奔腾 (i386/i486 arch) 中。

为了能够跟踪,我生成了一个核心转储。让我们跟随它:

iguana$gdb xadreco core-20131207-150611.dump

Core was generated by `./xadreco'.
Program terminated with signal 11, Segmentation fault.
#0  0xb767fef5 in ?? () from /lib/i386-linux-gnu/libc.so.6
(gdb) bt
#0  0xb767fef5 in ?? () from /lib/i386-linux-gnu/libc.so.6
#1  0xb76824bc in malloc () from /lib/i386-linux-gnu/libc.so.6
#2  0x080529c3 in enche_pmovi (cabeca=0xbfd40de0, pmovi=0x...) at xadreco.c:4519
#3  0x0804b93a in geramov (tabu=..., nmovi=0xbfd411f8) at xadreco.c:1473
#4  0x0804e7b7 in minimax (atual=..., deep=1, alfa=-105000, bet...) at xadreco.c:2778
#5  0x0804e9fa in minimax (atual=..., deep=0, alfa=-105000, bet...) at xadreco.c:2827
#6  0x0804de62 in compjoga (tabu=0xbfd41924) at xadreco.c:2508
#7  0x080490b5 in main (argc=1, argv=0xbfd41b24) at xadreco.c:604
(gdb) frame 2
#2  0x080529c3 in enche_pmovi (cabeca=0xbfd40de0, pmovi=0x ...) at xadreco.c:4519
4519        movimento *paux = (movimento *) malloc (sizeof (movimento));
(gdb) l
4516 
4517    void enche_pmovi (movimento **cabeca, movimento **pmovi, int c0, int c1, int c2, int c3, int p, int r, int e, int f, int *nmovi)
4518    {
4519        movimento *paux = (movimento *) malloc (sizeof (movimento));
4520        if (paux == NULL)
4521            exit(1);

当然,我需要查看第 2 帧,这是堆栈中与我的代码相关的最后一个帧。但是 4519 行给出了 SIGSEGV!它没有时间在第 4520 行测试 paux==NULL 与否。

这是“movimento”(缩写):

typedef struct smovimento
{
    int lance[4];  //move in integer notation
    int roque; // etc. ...

    struct smovimento *prox;// pointer to next
} movimento;

该程序可以加载大量内存。我知道内存力已经到了极限。但我认为当内存不可用时,malloc 会处理得更好。

在执行过程中执行$free -h,我可以看到内存低至 1MB!没关系。旧电脑只有 96MB。操作系统使用了 50MB。

我不知道从哪里开始寻找。也许在 malloc 调用之前检查可用内存?但这听起来是对计算机能力的浪费,因为 malloc 应该会这样做。 sizeof (movimento) 约为48 字节。如果我之前测试过,至少我会对这个错误有一些确认。

有什么想法,欢迎分享。谢谢。

最佳答案

任何malloc(或free)内的崩溃几乎都是堆损坏的迹象,它可以有多种形式:

  • 堆缓冲区上溢或下溢
  • 释放某物两次
  • 释放非堆指针
  • 写入已释放的 block
  • 等等

如果没有工具支持,这些错误很难捕获,因为崩溃通常会出现数千条指令,并且可能会在代码中多次调用 mallocfree这通常位于程序的完全不同的部分,并且距离错误所在的地方很远。

好消息是 Valgrind 等工具或AddressSanitizer通常会直接指出问题所在。

关于c - malloc 中的信号 11 SIGSEGV?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20445276/

相关文章:

c - 如何设计一个可扩展到恰好 n 个元素的哈希函数?

linux - 更改 linux 内存保护

c - 通过函数参数从另一个文件访问静态全局数组

c - 插入三元搜索树中的段错误

c - 段错误或可疑的指针到指针转换(区域太小)

c - 我怎样才能让 GetKeyState 理解大写和非大写字母

c++ - 表示纪元之前的日期

c - 从文件 c 中读取多位整数

android - PNG 和 JPEG 内存分配的区别

hibernate - 在 Grails/Tomcat 上的长批处理期间出现 OutOfMemoryError