为什么malloc在这里返回NULL?

问题描述:

所以我的程序总是返回分段错误,但我不明白为什么那么试着用GDB调试,它表明我这个:为什么malloc在这里返回NULL?

(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,但我看不出这条线的问题,一切都proprely初始化为我和我的下一个确认动作:

(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) 

EDIT2:

我终于为我所用它上化妆的时候,我应该使用它的程序本身(在评论所示)使用的valgrind正确地理解问题。问题是在一个非常不同的地方,在一个地方,我忘了写一个malloc,感谢大家的帮助下,现在我终于明白,我应该怎么Valgrind的使用

+6

我不知道看不到调试会话在哪里告诉你'malloc'返回null。它看起来像在'malloc'本身内部死亡,指向损坏的内存。 – Kaz

+3

由于您显然在GNU/Linux上,请安装Valgrind并在其下运行您的程序;然后仔细阅读其错误报告。 Valgrind经常能够找到并查明未被发现的问题,这些问题将在以后导致崩溃和错误行为。例如,在程序的一个模块中有一个缓冲区溢出,这会破坏'malloc'堆,这样一个完全不相关的模块中正确的'malloc'调用就会崩溃。 – Kaz

+0

这是从用户空间上下文实际调用的malloc吗? – jada12276

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

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

我觉得你的问题是与顺便做你”重新使用malloc。 Malloc分配一块内存字节,返回一个指针到块的开始。你应该写:

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

事实上,除非c是一个指向一个结构,它是非法的写C-> TIPO = -1;。例如,c - > tipo中的 - >运算符是*(c).tipo的快捷键。

+2

如果大写'Capsula'是'typedef struct capsula * Capsula',那么没有任何错误。 – Kaz

+3

OP最有可能隐藏在typedefs后面的指针:'typedef struct capsula * Capsula;'。这被认为是不好的风格,你的误解是它适得其反的原因。 – chqrlie

+2

你说的是正确的,但是我的结构是capsula和Capsula是它的指针,正如我在我的问题上所说的。但是,无论如何感谢您的回答:) –

如果调试器显示你在这一行触发分段错误:

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

它有两个含义:

  • c是一个坏的指针,可能NULL,但以前的声明c->typo = -1;也应该失败。

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