2010-10-13 438 views
4
int main() 
{ 
    int * b; 
    b = (int*) malloc (1); 
    *b=110000; 
    free (b); 
    return 0; 
} 

爲什麼堆腐敗發生在free (b);C中的堆損壞

IMO,堆腐敗已發生在*b=110000;

+2

僅供參考,您不需要投射malloc。 – Nyan 2010-10-13 13:35:16

+0

你跟Valgrind覈對過嗎?這將告訴你在哪裏發生了非法寫入,這應該是上述示例中的第5行。 – Christoffer 2010-10-13 14:28:09

回答

12

malloc()的參數是要分配的字節數。您需要使用:

b = (int*) malloc(sizeof(int)); 

您已經分配過小的塊,然後寫比你分配,其旁邊塊覆蓋簿記信息,損壞堆更多的字節給它。

+0

我的問題是爲什麼'* b = 110000;'因爲它使用的空間比可用空間更多而沒有損壞? – Alan 2010-10-13 11:55:39

+14

腐敗堆的任務是檢測腐敗的免費調用。 – 2010-10-13 11:58:00

+1

@Alan - 它會破壞你的堆。只是你可能會立即看到後果,也可能看不到後果。 – 2010-10-13 11:58:43

5

它在* b = 110000;因爲您正在爲一個字節分配內存,然後爲其分配一個不止一個字節的int。要麼你可以有b =(int *)malloc(sizeof(int)),而不是int * b,你可以有char * b,然後將指針指向char *。如果您爲* b分配的值小於128(由於signed char),代碼甚至可能會工作。

編輯: - 我認爲有時甚至這將工作沒有任何麻煩。因爲編譯器可能會選擇分配多個字節的內存來快速訪問數據。

4

堆腐敗確實發生在*b=11000分配上,但直到free(b)調用才被檢測到,因爲這是再次檢查堆完整性的第一個點。

檢查每個賦值(甚至每個涉及解引用指針的賦值)時的堆完整性會使大多數程序減慢太多,並且會使編譯器與庫實現緊密聯繫在一起。出於這個原因,完整性檢查僅在堆被操縱時執行,這在mallocfree函數(和朋友)中。

0

代碼將更多數據寫入內存塊,而不是可用空間,因此會破壞下一個有效內存塊的開始。

使用char *而不是int *並寫入值-128到127到* b應該修復它。