2011-06-21 54 views
17

我對下面的情況(這是我在一些代碼,我有工作發現的)特別想知道:我可以刪除[]指向已分配數組的指針,但不指向它的開始位置?

SomeClass *ar = new SomeClass[2]; 
ar++; 
delete[] ar; 

此代碼似乎是做工精細 - 即不崩潰(win32的,與VS2005建) 。

這是「合法的」嗎?這當然不舒服。

+3

「似乎工作正常」 - 是的,但*它是*? :P – Marlon

+1

這會在Vista和Win7上很好地轟炸你的程序。時間溝XP。 –

+5

@Marlon--這不完全是我的問題嗎? – sje397

回答

21

不,它是undefined將任何地址傳遞到delete這是不是由new返回。
以下是標準報價。

§3.7.4.2-3

如果釋放函數拋出一個異常終止,該行爲是不確定的。提供給釋放函數的第一個參數的值可能是空指針值;如果是這樣,並且如果釋放函數是標準庫中提供的函數,則該調用不起作用。否則,向標準庫中的運營商delete(void*)提供的值 應該是先前調用標準庫中的運營商new(std::size_t)operator new(std::size_t, const std::nothrow_-t&)所返回的值中的一個,並且在標準庫中提供給運營商delete[](void*)的值應該是先前在標準庫中調用operator new[](std::size_t)operator new[](std::size_t, const std::nothrow_t&)返回的值。

20

不,不合法。你只能得到delete你從new得到的結果,同樣適用於new[]delete[]

7

不,它不是。您必須在您從new []收到的相同地址(或指針)上調用delete []。你可能會很幸運,它不會崩潰,但它絕對不會適當地清除內存。

參考文獻:

http://www.cplusplus.com/doc/tutorial/dynamic/

The value passed as argument to delete must be either a pointer to a memory block 
previously allocated with new, or a null pointer (in the case of a null pointer, 
delete produces no effect). 

http://msdn.microsoft.com/en-us/library/h6227113.aspx

Using delete on a pointer to an object not allocated with new gives 
unpredictable results. You can, however, use delete on a pointer with the 
value 0. This provision means that, when new returns 0 on failure, deleting 
the result of a failed new operation is harmless. 
0

這是不合法的事實,即它不會崩潰,並不意味着它不會在其他情況下。如果啓用驗證程序,它肯定會崩潰。無論如何它不會釋放你的陣列。這只是CRT/Windows讓你的程序不應該崩潰時,它應該

6

從標準文檔中, 5.3.5.2 Delete

...在第二 替代(刪除陣列)的刪除操作數的值應導致從先前 陣列新expression.72指針值)如果不是,則行爲未定義。 ....

此外子音符72)指出,

72)對於非零長度數組,這是相同的一個指針通過創建的數組的第一個元素那個新表達。零長度數組不包含 有第一個元素。

所以是的,它是未定義的。

1

該標準規定您只能刪除新分配的內容,但這並不能解釋爲什麼它會崩潰,或者在這種情況下不會崩潰。

當你刪除一個指針時,你將它放回堆中,以便在將來的分配中再次使用。 典型的實現爲您提供了一個指針,在指針跟蹤塊中的內存(這是典型的malloc實現)之前有一個int。像這樣,對於典型的32位系統。

 p-4 size here 
p-->  +--------+ 
     | your | 
     | block | 

所以,如果你點成塊的中間,它會之前它來解釋字節的大小,具有潛在災難性的結果。您從您的小代碼示例中看到了崩潰。也許,你從來沒有試過在那之後分配。如果你嘗試在那之後分配一些東西,它可能會崩潰,因爲它會嘗試回收你剛回來的一些內存。

確切的原因顯然取決於實施。這僅僅是解釋一個常用的方法刪除不當可能會失敗,沒有具體覈實爲Visual Studio 2005

+0

實際上,在實際的代碼中,char數組被分配來接收非常頻繁的套接字消息,但是在解析消息時修改指向緩衝區的指針。然後使用修改後的指針刪除[]。可怕的東西。 – sje397

0

enter image description here

如果不通過它的開始,delete不會得到額外的信息。