2014-04-04 50 views
0

我正在實現內存分配器。我目前滿足這個問題內存分配器:避免空閒內存兩次

void deallocate(void* ptr) { 
    // code to deallocate memory start at ptr 
} 

// client test code 
printf("Test : deallocate same pointer two times \n"); 
char* ptr = (char*) allocate(32); 
deallocate(ptr); 
deallocate(ptr); // ERROR 

因爲DEALLOCATE(由反正),就在指針PTR可用內存。地址存儲在ptr中仍然像以前一樣,我不能將它設置爲NULL(因爲參數是一個指針,而不是指針的指針)。

所以我的問題是:我怎樣才能防止分配相同的指針兩次上述場景?

謝謝:)

+0

你有'deallocate/alocate'實現的簿記數據嗎?如果是這樣,你可以使用它們來跟蹤釋放的內存。在已釋放的內存上調用「釋放」時,會顯示警告。 –

回答

1

如果你想阻止一個解決方案是跟蹤已傳遞到free版本的所有地址:調用free時,首先檢查ptr是否已傳遞給您(例如,通過在地圖/散列表中搜索該密鑰)。如果它存在,你什麼都不做;否則你需要輸入ptr到數據結構中,然後繼續做你需要做的事情。

當然,這並不是那麼簡單:當您進行分配時,還需要從數據結構中刪除ptr。如果您在地址addr處分配size字節,則您需要刪除ptr如果addr <= ptr <= addr+size

然而,假設你正在實現任何一種明智的內存管理器,你將已經擁有一個空閒池(一個未分配或已分配和已被釋放的塊的列表),甚至可能還有一個已分配的鏈表塊。

在這種情況下,您可以簡單地遍歷空閒池以查看被釋放的塊是否已經在空閒池中列出,如果是,則什麼也不做。或者,也可以迭代分配的塊的列表,並確保你被要求釋放的東西確實被分配。

當然,正如其他人已經指出的那樣,這通常是調用者而不是分配器的責任,儘管在分配器中具有這種功能對調試目的很有用。

+0

我在網絡上看到很多內存分配器庫。是否存在實現此功能的任何庫?謝謝:) –

+0

並感謝您的想法:) –

+0

在調試模式下,隨Windows附帶的C標準庫中的標準內存分配器會執行。還有一些UNIX庫也可以實現這種檢查,但我沒有名字。 –

2

分配器不防止這種情況。這不是分配器的責任,而是分配器用戶關心雙重刪除的責任。

如果您真的希望您的釋放器擁有這種防呆機制,則需要在分配器實現中將所有已分配指針的表存儲在全局變量中。然後解除分配器首先檢查指針是否被註冊,如果是,則釋放並從表中移除指針。當然,您需要一個非常高效的表格容器,對插入,刪除和查找的複雜度較低。

0

只要你釋放內存,NULL指針,如果你對NULL指針調用free,也不會有例外,

一樣,

deallocate(ptr); 
ptr = NULL; 
deallocate(ptr); // NO ERROR 
+0

這是否會失敗真的取決於'deallocate()'裏面發生了什麼。 – alk

+0

@alk真的。但是,函數名稱暗示,它調用delete。如果你打電話給刪除兩次,錯誤將是肯定的。 –

+0

如果它是'刪除',我會忽略寫過'delete'的OP,不會嗎?我們也在這裏說C,而不是C++,不是嗎? – alk