2008-11-19 24 views
6

我知道我在使用new []之後應該使用delete [],所以使用auto_ptrnew []並不是這樣一個好主意。在Visual C++中刪除和刪除[]相同嗎?

然而,在調試delete [](使用Visual Studio 2005),我注意到,在呼叫進入一個看起來像這樣的功能:

void operator delete[](void * p) 
{ 
    RTCCALLBACK(_RTC_Free_hook, (p, 0)) 
    operator delete(p); 
} 

這是否意味着,在[]語法失去的Visual C++?如果是這樣,爲什麼?是爲了減輕開發人員記住正確語法的負擔嗎?

+0

`delete [] p`不等於`operator delete [](p)`。 – 2011-05-12 00:38:28

回答

26

考慮以下代碼:

class DeleteMe 
{ 
public: 
    ~DeleteMe() 
    { 
    std::cout << "Thanks mate, I'm gone!\n"; 
    } 
}; 

int main() 
{ 
    DeleteMe *arr = new DeleteMe[5]; 
    delete arr; 
    return 0; 
} 

如果運行在VS2005它將打印:

Thanks mate, I'm gone!

如果更改main()正確地堅持C++標準:

int main() 
{ 
    DeleteMe *arr = new DeleteMe[5]; 
    delete[] arr; 
    return 0; 
} 

它會打印:

Thanks mate, I'm gone! 
Thanks mate, I'm gone! 
Thanks mate, I'm gone! 
Thanks mate, I'm gone! 
Thanks mate, I'm gone!

不要將自己打在腳上。 VS2005將不是做正確的事情,如果你不匹配不同口味的新/刪除。任何其他C++標準一致的編譯器都不會。

operator newoperator delete(以及它們的不同風味)周圍存在着一些編譯器魔法,基本上,調用ctors和dtors是在幕後添加的。這個魔法取決於那些小括號[],所以不要失去它們,否則你會失去魔法。

2

僅僅因爲他們現在可能同樣工作,並不意味着你可以一定對待他們 - 行爲可能會改變。此外,誰在乎 - 你應該寫你的代碼,所以你不必記住。您可以使用scoped_array進行數組刪除。

+0

我知道,我們應該,但到目前爲止,我們不使用Boost。:( – 2008-11-19 09:39:35

+0

我相信scoped_array(和其他Boost智能指針類型)是TR1的一部分,你可能已經有他們沒有提升 – Ferruccio 2008-11-19 13:18:53

+0

我錯過了有關VS2005的部分,我認爲TR1在VS2008 SP1 – Ferruccio 2008-11-19 13:19:52

4

我想這只是一個實現細節。當釋放數組和指針時,它們的堆分配器的工作方式相同。

但由於該標準允許實現針對兩種情況具有不同的算法,所以您確實不應該認爲deletedelete[]可以做同樣的事情。編譯器版本之間的行爲甚至可能會改變。

2

也許你刪除的數據沒有析構函數?如果是這樣,這個簡單的刪除將是有道理的。畢竟它正在處理void *。

無論如何,你應該使用delete []來確保爲數組中的每個元素運行析構函數。

2

刪除沒有[]的數組只會釋放內存,但不會調用數組中每個對象的析構函數。所以,從技術上講,如果你的析構函數需要被調用,你只需要[]。