2013-05-29 164 views
0

如何釋放空指針。釋放空指針

struct vStruct { 
    void *vPtr; 
    struct vStruct *next; 
}; 

struct vStruct sObj; 
struct vStruct *sObjNew = sObj; 

delete sObjNew->vPtr; -----------> Is this correct way to delete void pointer 
delete sObjNew; 

顯示錯誤操作「刪除」,應用到void *的說法已經是未定義行爲,而且極有可能不會調用對象的析構函數。

+0

如果其中一個答案解決了您的問題,請不要忘記將其標記爲已接受,這樣可以幫助更多訪問者訪問此網站。 – Spook

回答

3

您不應該刪除void指針。 delete適用於特定類型(例如,編譯器知道應該調用哪個析構函數 - 如錯誤消息中所述)。

如果你想在你的結構中保持未指定的類型,你必須以某種方式包裝它。

class DataWrapper 
{ 
public: 
    virtual void * GetData() = 0;    
    virtual ~DataWrapper() 
    { 
    } 
}; 

class MyDataWrapper 
{ 
protected: 
    MyData * data; 

public: 
    MyDataWrapper(MyData * newData) 
    { 
     data = newData; 
    } 

    void * GetData() 
    { 
     return data; 
    } 

    ~MyDataWrapper() 
    { 
     delete data; 
    } 
}; 

struct vStruct 
{ 
    MyDataWrapper * vPtr; 
    struct vStruct *next; 

    ~vStruct() 
    { 
     if (vPtr != null) 
      delete vPtr; 
    } 
}; 

vStruct sObj; 
sObj.vPtr = new MyDataWrapper(new MyData()); 

// When sObj gets deleted, MyDataWrapper is 
// deleted too (thanks to the ~vStruct) and 
// in effect, the allocated data is deleted too. 

請注意,這是一個簡單的例子,它可以寫得更美觀。

9

你沒有delete一個void指針。爲什麼?因爲:

'delete',應用於void*參數具有未定義的行爲,並且很可能不會調用該對象的析構函數。

您的編譯器將如何知道指針對象具有哪種類型?並因此調用哪個析構函數? (儘管它可能會根據分配機制確定要釋放多少內存。)

不存儲void* —改爲使用「真實」指針類型。如果你需要「隱藏」真正的類型,考慮採用多態性而不是陳舊的C實踐。

3

vPtr如何初始化?

  • 如果它指向數據結構不擁有,你不能銷燬它。
  • 如果它指向使用malloc創建的數據,則應該調用free
  • 如果它指向使用new創建的數據,則在調用delete以允許調用正確的析構函數之前,需要將其轉換爲正確的(或兼容)類型。

請注意,您的示例代碼不會編譯,但建議vPtr根本沒有被初始化。您必須在您創建的所有vStruct實例中初始化vPtr。試圖釋放未初始化的vPtr將會導致未定義的後果,但可能會崩潰。