2017-04-05 32 views
-1

在實際項目中調試分段錯誤時,在長時間運行後發生崩潰並且隨機測試不容易重現。崩潰點顯示崩潰的函數寫入類似於可以在動態分配的內存上調用memset導致堆損壞

void deallocateObject(objectType* ptr) 
{ 
    ASSERT(ptr); 
    if(!ptr) 
     return; 
    if(ptr->customDeallocator) 
     ptr->customDeallocator->deallocate(); 
    else 
     free(ptr); 
} 

在項目中使用了各種類型的allocator和deallocator。 爲了驗證分段錯誤不是因爲分配的內存在釋放後未被設置爲NULL,我在此函數中的最後一條語句之後向memset添加了一個調用。

memset(ptr, 0, sizeof(objectType)); 

但是在這個改變之後,我開始每次都有崩潰的消息說堆已損壞。

所以我的問題是如何以及在什麼情況下調用memset()可能導致堆損壞。

+8

您在'free(ptr)'之後調用'memset(ptr ...'?顯然這是未定義的行爲 –

+0

不能觸及釋放的內存使用像Valgrind這樣的工具來調試內存錯誤 –

+0

聲明之後, d你再次檢查NULL? –

回答

3

所以我的問題是如何以及在什麼情況下調用memset()會導致堆損壞。

任何時候用它來修改可能用於跟蹤堆內部結構的內存。例如,您剛剛告訴堆分配器的內存已經完成,並且現在可以自由用於任何目的,例如跟蹤堆的內部結構。

0

如果只想驗證分割故障是不是因爲被設置爲NULL釋放

好後分配的內存不,這是你調試沒有如何動態分配的內存相關的問題。就進一步的重新分配而言,包含NULL的指針與已經傳遞給內存的指針無效。

所以,無論是已經free() -d指針(手動)設置爲NULL與否,進一步使用該指針的(間接引用)會導致undefined behavior,你可能會或可能不會得到一個分割故障,對於某些,這只是UB的許多副作用之一。

您需要使用內存調試器,如valgrind來捕獲並解決問題。

FWIW,任何使用無效內存的嘗試(包括NULL,是)調用UB,避免這種情況。