C语言 为什么 malloc 在这里返回 NULL



所以我的程序总是返回分段错误,但我不明白为什么如此尝试使用 GDB 进行调试,它向我展示了以下内容:

(gdb) backtrace
#0  0x001a98ef in _int_malloc (av=0x2d8440, bytes=8) at malloc.c:3835
#1  0x001abedc in __GI___libc_malloc (bytes=8) at malloc.c:2924
#2  0x0804cd6a in init_capsula (item1_=2, item2_=2)
    at src/modulos/modulos_auxiliares/capsula/capsula.c:25
#3  0x0804d366 in total_dados_produto (f=0x8055838, filial=0x0, mes=6, 
    cod=0xbffff23c "AF1184") at src/modulos/faturacao/faturacao.c:208
#4  0x0804b237 in queries (q=3, c1=0x0, c2=0x0, f=0x8055838, v=0x0) at src/interface.c:815
#5  0x0804b6f4 in menu (c1=0x8055008, c2=0x8055420, f=0x8055838, v=0x0) at src/interface.c:976
#6  0x080487ad in main () at src/interface.c:1037

然后,我确定了问题的根源来自第 2 帧,因此决定检查一下并得到以下输出:

(gdb) frame 2
#2  0x0804cd6a in init_capsula (item1_=2, item2_=2)
    at src/modulos/modulos_auxiliares/capsula/capsula.c:25
25          c->item1 = (int*) malloc((sizeof (int))*item1_);

它告诉我 malloc 返回一个 NULL,但是我看不到这一行的问题,当我在下一个操作中确认时,一切都被提前初始化:

(gdb) print ((sizeof (int))*item1_)
$1 = 8

为什么 malloc 不能分配这么小的空间?我在这里是不是有些愚蠢的事情???

我将函数init_capsula放在这里(那个malloc所在的那个),供你们查看:

Capsula init_capsula(int item1_, int item2_){
     Capsula c = (Capsula) malloc (sizeof (struct capsula));
     c->tipo  = -1;
     if (item1_ > 0)
         c->item1 = (int*) malloc((sizeof (int))*item1_); /*Problematic line*/
     else c->item1 = NULL;
     if (item2_ > 0)
         c->item2 = (float*) malloc((sizeof (float))*item2_);
     else c->item2 = NULL;
     c->q1 = 0;
     c->q2 = 0;
     return c;
}

Capsula 是一个指向结构的指针,定义如下:

struct capsula{
    int tipo;
    int     q1;
    int *item1;
    int       q2;
    float *item2;
 };

编辑:

如果我尝试使用以下命令运行 valgrind:

     valgrind --tool=memcheck --leak-check=full make run

它输出这个,我觉得不是很有帮助。

    make: *** [run] Segmentation fault (core dumped)
    ==5848== 
    ==5848== HEAP SUMMARY:
    ==5848==     in use at exit: 62,771 bytes in 1,819 blocks
    ==5848==   total heap usage: 6,060 allocs, 4,241 frees, 580,609 bytes allocated
    ==5848== 
    ==5848== LEAK SUMMARY:
    ==5848==    definitely lost: 0 bytes in 0 blocks
    ==5848==    indirectly lost: 0 bytes in 0 blocks
    ==5848==      possibly lost: 0 bytes in 0 blocks
    ==5848==    still reachable: 62,771 bytes in 1,819 blocks
    ==5848==         suppressed: 0 bytes in 0 blocks
    ==5848== Reachable blocks (those to which a pointer was found) are not shown.
    ==5848== To see them, rerun with: --leak-check=full --show-reachable=yes
    ==5848== 
    ==5848== For counts of detected and suppressed errors, rerun with: -v
    ==5848== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

编辑2:

我终于通过正确使用 valgrind 来理解这个问题,因为我应该在程序本身使用它时在制作中使用它(如评论所示)。问题出在一个非常不同的地方,在一个我忘了写malloc的地方,感谢所有帮助过我的人,现在我终于明白我应该如何使用valgrind

如果调试器显示您正在此行触发分段错误:

c->item1 = (int*) malloc((sizeof (int))*item1_);

这可能意味着两件事:

  • c是一个糟糕的指针,可能是NULL,但前面的语句c->typo = -1;也应该失败。

  • 竞技场
  • 可能已损坏,问题出在到达竞技场之前执行的代码。

我正在回答我自己的问题,因为正如我在上次编辑中所说,我在评论的帮助下找到了答案。

我终于通过正确使用 valgrind 来理解这个问题,因为我应该在程序本身使用它时在制作中使用它(如评论所示)。问题出在一个非常不同的地方,在一个我忘了写 malloc 的地方,所以没有必要详细介绍,感谢所有帮助过的人,现在我终于明白我应该如何使用 valgrind

我认为您的问题与您使用 malloc 的方式有关。Malloc 分配一个字节内存块,返回一个指向块开头的指针。你应该写:

Capsula * c = (Capsula *) malloc (sizeof (struct capsula));

实际上,除非 c 是指向结构的指针,否则编写 c->tipo = -1; 是非法的。例如,c->tipo 中的 -> 运算符是 *(c).tipo 的快捷方式。

相关内容

  • 没有找到相关文章

最新更新