char* x = malloc(512);
memset(x, 0, 513);
free(x);
這是爲什麼這個程序崩潰?這是說free(): invalid pointer: 0x0000000000614010
這沒有任何意義,如果有的話它應該破壞程序的一些其他隨機部分,因爲它寫入未定義的內存空間。爲什麼這個指針無效?
char* x = malloc(512);
memset(x, 0, 513);
free(x);
這是爲什麼這個程序崩潰?這是說free(): invalid pointer: 0x0000000000614010
這沒有任何意義,如果有的話它應該破壞程序的一些其他隨機部分,因爲它寫入未定義的內存空間。爲什麼這個指針無效?
您已經分配了512字節的內存,但正在向其寫入513個字節。 free()
大概是檢查內存區域是否仍然有效(如果它包含您寫過的保護字節,則不會)。
我是新來的,但我希望我能回答這個問題,讓您滿意。
您正在通過覆蓋分配的塊的重要部分來激發未定義的行爲。您正在刪除該塊上大小信息的第一個(高位字節),即由malloc
編寫。大多數C標準庫使用Doug Lea Malloc追加和prepends一些字節到您的塊,它們包含大小和使用信息。通過覆蓋這個,你實際上銷燬了free()
調用成功所需的信息,並真正釋放了malloc的內存。 malloc
的某些實現不會這樣做,併爲塊對齊和大小保留一個「帶外」表(其他位置,而不覆蓋它),並且一些只是預先附加/追加該信息。正如我所說,你的程序崩潰,因爲你覆蓋了重要的信息,沒有它,free()
就是不能做它應該做的事情。
堆分配器在分配內存之前和/或之後立即放置一些簿記信息是很常見的。你觀察到的一個可能的解釋是你已經覆蓋了對內存分配器的操作至關重要的一些數據,可能是分配的塊的大小或下一個可用空間的位置。
在任何情況下,在您分配的空間範圍之外寫入都是未定義的行爲,並且可能發生任何事情。僅僅因爲這是現在發生的事情並不意味着它會發生在不同的系統上,甚至在不同的時間在同一個系統上。相反,即使你沒有看到錯誤,這並不意味着未定義的行爲不會被調用。這是使用不安全語言的成本,例如C.
[鼻惡魔](http://catb.org/jargon/html/N/nasal-demons.html)! – ephemient