2016-03-15 76 views
1

所以我的程序總是返回分段錯誤,但我不明白爲什麼那麼試着用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

回答

1

我在回答我自己的問題,因爲正如我在上次編輯時所說的,我在評論的幫助下找到了我的答案。

當我在程序本身上使用它時(正如註釋中所示),我終於正確地使用了valgrind,因爲我正在使用它。問題出在一個非常不同的地方,在一個我忘記寫malloc的地方,所以沒有必要詳細介紹,感謝所有幫助過我的人,現在我終於明白我應該如何使用valgrind

0

我覺得你的問題是與順便做你」重新使用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是它的指針,正如我在我的問題上所說的。但是,無論如何感謝您的回答:) –

2

如果調試器顯示你在這一行觸發分段錯誤:

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

它有兩個含義:

  • c是一個壞的指針,可能NULL,但以前的聲明c->typo = -1;也應該失敗。

  • 競技場可能損壞,問題出現在代碼執行之前。