2008-10-24 103 views
9

我正在執行一個任務的尾部。我有它正常工作,但我似乎從隨機時間免費獲得一個錯誤。Malloc錯誤:釋放對象的校驗和不正確

我看不到,要追蹤到一個模式或除了它是一致的任何東西。

例如,如果我將我的程序稱爲「tail -24 test.in」,我會在多次運行的同一行上得到不正確的校驗和錯誤。但是,使用不同的文件甚至不同數量的行來打印回來,我將無錯地回來。

關於如何追蹤問題的任何想法,我一直試圖調試它幾個小時無濟於事。

這裏是有問題的代碼:

線被定義爲一個char **,是的malloc爲:

lines = (char**) malloc(nlines * sizeof(char *)); 

void insert_line(char *s, int len){ 

    printf("\t\tLine Number: %d Putting a %d line into slot: %d\n",processed,len,slot); 
    if(processed > numlines -1){//clean up 
    free(*(lines+slot)); 
    *(lines + slot) = NULL; 
    } 
    *(lines + slot) = (char *) malloc(len * sizeof(char)); 
    if(*(lines + slot) == NULL) exit(EXIT_FAILURE); 
    strcpy(*(lines+slot),s); 
    slot = ++processed % numlines; 
} 
+0

是插槽0或1,根據? 插槽永遠不會超過nlines-1,正確嗎? – Dre 2008-10-24 07:10:09

+0

right模數自動回到0 – None 2008-10-24 07:15:13

+0

您使用哪個編譯器和哪個調試器?根據這一點,他們可能會提供一些調試問題的幫助。 – 2008-10-24 08:03:43

回答

7

你的例程寫入超出了分配的行緩衝區。

作爲參數傳遞的行的大小(即「len」)可能不包括NUL終止符。當你調用malloc複製行(即「S」),你需要爲一個字符串結束分配一個額外的字節:

*(lines + slot) = (char *) malloc((len + 1) * sizeof(char)); 
0

做nlines和numlines具有相同的價值?

當傳遞第二個參數的長度時,insert_line的調用者是否爲尾隨NUL留出空間?

+0

是的,nlines和numlines是相同的值。線的實際聲明發生在別的地方。空值由調用函數進行計算。 – None 2008-10-24 07:16:27

0

我不知道它是相關的,但這兩行看起來可疑對我說:

*(lines + slot) = (char *) malloc(len * sizeof(char)); 
    if((lines + slot) == NULL) exit(EXIT_FAILURE); 

你先malloc的返回分配給lines[slot],然後你檢查(lines+slot),如果後者是NULL,你有解引用NULL指針!

此外,如果lines [slot](您的*(lines + slot))不爲null,則會在將malloc()的結果賦給它時泄漏內存。

我假設lineschar * lines []`並且slot在允許的邊界內!

0

我同意REM對這兩條線的懷疑,但不同意REM給出的切線。我們應該分享功勞來找到這個錯誤。

*(lines + slot) = some value 
if((lines + slot) == NULL) then die 
should be 
if(*(lines + slot) == NULL) then die 
3

如果可以一致地重現與特定輸入參數的問題,您應該調試是這樣的:

  • 首先調試的精確自由引起該問題。
  • 然後計算出將要被釋放的內存何時被malloc化。
  • 接下來,調試到內存malloc'ed的地方。
  • 在內存查看器中找到已分配的內存塊。注意塊的開始和結束。在該塊之前和之後可能有一個特殊值,稱爲保護塊
  • 現在遍歷代碼,直到內存被釋放。在某些時候,你的代碼應該錯誤地覆蓋了保護塊。 這是違規的陳述。

請注意,該問題可能很好地在您的程序的一個完全不同的部分。即使報告錯誤是免費的,覆蓋保護塊的代碼可以在任何地方。

1

我的第一個問題是你如何計算len?它只是strlen還是它包含了\ 0終止符的空間?我想你可能會在你的strcpy中超出你的分配。不良行爲將傾向於發生在單詞邊界上,並呈現隨機性。另外,請檢查以確保您的源字符串是空終止的。如果你在閱讀方面犯了錯誤,並沒有終止它們。然後strcpy可能會隨機覆蓋事物。

*(lines + slot) = (char *) malloc(len * sizeof(char)); 
    if(*(lines + slot) == NULL) exit(EXIT_FAILURE); 
    strcpy(*(lines+slot),s); 

也許嘗試:

lines[slot] = (char *) malloc((len + 1) * sizeof(char)); 
    if(lines[slot] == NULL) exit(EXIT_FAILURE); 
    if(strlen(s) <= len){ 
    strcpy(lines[slot],s); 
    } 
    else{ 
    /* do something else... */ 
    } 

在一般形式而言,我也建議你作一些文體上的修改,使整個事情有點更具可讀性,更易於理解和耐錯誤。

指針運算是有效的和有趣的,但我覺得你的目的是更加清楚一點,如果你使用像數組形式:

free(lines[slot]); 
lines[slot] = NULL; 

,而不是

free(*(lines+slot)); 
*(lines + slot) = NULL; 

我也鼓勵你使用更少的靜態。在數據結構中通過它們很容易,並將它們傳遞給您的訪問器和增變器。它變得更加清晰,其中的動作是發生阻止你做這樣的事情:

static int numlines = 0; 
void insert_line(char *s, int len){ 
    int numlines = 5; 

在這裏您可以引入範圍的問題是隻可憐的調試。

相關問題