2016-02-14 65 views
1

我已經給了一個面試問題來寫一個內存管理器(內存池)。我差不多完成了,但我在解除分配時遇到問題。尋求幫助也很好,就像我們提到幫助的來源一樣。所以,請幫我如何檢查指針在C++中是否有效?

int main(void) 
{ 
    using namespace PoolOfMemory; 

    initializePoolOfMemory(); // Initialize a char array as the memory pool 

    long* int_pointer; 

    int_pointer = (long *) allocate(sizeof(long)); //allocate is defined in PoolOfMemory and it returns void*. 

    int_pointer = 0xDEADBEEF; 

    deallocate(int_pointer); 
} 

現在我的問題是,當「取消分配」試圖int_pointer解除分配,它拋出一個訪問衝突錯誤,顯然是因爲我想訪問0xDEADBEEF。以下是我的簡單釋放功能:

void deallocate(void* p) 
{ 
    Header* start = (Header*)((char*)p-sizeof(Header)); 
    start->free=true; //This is where I get access violation.; 
} 

我該如何避免這種情況?根據我在網上閱讀的內容,我假設檢查p是否在我的數組中,是行不通的。

+4

顯而易見的答案是不操縱指針直接指向的內存位置的值...我無法想象爲什麼你會分配內存,然後指向這種方式的任意位置。除非您使用第三方庫進行內存管理,這是專門設計用於防止您釋放不在其分配的區域內的指針(這會增加相當多的開銷),您必須遵循良好的指針規則並編寫乾淨的代碼。 –

+0

請參閱http://stackoverflow.com/questions/496034/most-efficient-replacement-for-isbadreadptr和http://stackoverflow.com/questions/17202570/c-is-it-possible-to-determine-whether-一個指針指向一個有效的對象 –

+0

我明白你的觀點。但主要文件給了我,顯然他們希望代碼來處理這種情況。 – Sasan

回答

1

內存管理器傾向於更接近硬件級別,可能需要根據操作系統和CPU類型進行決策。

在這種情況下,您可能有理由打破一些C++抽象機器規則。例如,只需繼續並將指針與池數組的邊界進行比較即可。是的,在使用分段內存或可以形成陷阱指針的體系結構上,這可能會出錯,但您還有什麼要做?

之後,要驗證您有合適的指針,您可以讓分配器向分配標頭塊中寫入一個魔術值,在開始寫入自由布爾值和空閒塊指針之前,您可以在釋放函數中驗證該值,等

+0

謝謝@贊。使用神奇的數字聽起來不錯,但我很困惑如何做到這一點。假設在分配中,我在每個標題的開頭設置了一個幻數。當我傳遞了一個無效指針時,我該如何檢查它是否指向我的幻數?如果我嘗試訪問那個無效指針,我會得到一個訪問衝突錯誤。或者我是愚蠢的?! : -/ – Sasan

+0

@Sasan:首先計算指向頭部的指針。將其轉換爲'char *'或'uintptr_t'。然後將該指針與池數組的邊界進行比較。一旦你知道它在數組中,你知道它是安全的閱讀,並且你可以查找幻數。 –

+0

非常感謝。我實現了它,它工作。至少在我的機器上:) – Sasan