我對下面的情況(這是我在一些代碼,我有工作發現的)特別想知道:我可以刪除[]指向已分配數組的指針,但不指向它的開始位置?
SomeClass *ar = new SomeClass[2];
ar++;
delete[] ar;
此代碼似乎是做工精細 - 即不崩潰(win32的,與VS2005建) 。
這是「合法的」嗎?這當然不舒服。
我對下面的情況(這是我在一些代碼,我有工作發現的)特別想知道:我可以刪除[]指向已分配數組的指針,但不指向它的開始位置?
SomeClass *ar = new SomeClass[2];
ar++;
delete[] ar;
此代碼似乎是做工精細 - 即不崩潰(win32的,與VS2005建) 。
這是「合法的」嗎?這當然不舒服。
不,它是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&)
返回的值。
不,不合法。你只能得到delete
你從new
得到的結果,同樣適用於new[]
和delete[]
不,它不是。您必須在您從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.
這是不合法的事實,即它不會崩潰,並不意味着它不會在其他情況下。如果啓用驗證程序,它肯定會崩潰。無論如何它不會釋放你的陣列。這只是CRT/Windows讓你的程序不應該崩潰時,它應該
從標準文檔中, 5.3.5.2 Delete
,
...在第二 替代(刪除陣列)的刪除操作數的值應導致從先前 陣列新expression.72指針值)如果不是,則行爲未定義。 ....
此外子音符72)指出,
72)對於非零長度數組,這是相同的一個指針通過創建的數組的第一個元素那個新表達。零長度數組不包含 有第一個元素。
所以是的,它是未定義的。
該標準規定您只能刪除新分配的內容,但這並不能解釋爲什麼它會崩潰,或者在這種情況下不會崩潰。
當你刪除一個指針時,你將它放回堆中,以便在將來的分配中再次使用。 典型的實現爲您提供了一個指針,在指針跟蹤塊中的內存(這是典型的malloc實現)之前有一個int。像這樣,對於典型的32位系統。
p-4 size here
p--> +--------+
| your |
| block |
所以,如果你點成塊的中間,它會之前它來解釋字節的大小,具有潛在災難性的結果。您從您的小代碼示例中看到了崩潰。也許,你從來沒有試過在那之後分配。如果你嘗試在那之後分配一些東西,它可能會崩潰,因爲它會嘗試回收你剛回來的一些內存。
確切的原因顯然取決於實施。這僅僅是解釋一個常用的方法刪除不當可能會失敗,沒有具體覈實爲Visual Studio 2005
實際上,在實際的代碼中,char數組被分配來接收非常頻繁的套接字消息,但是在解析消息時修改指向緩衝區的指針。然後使用修改後的指針刪除[]。可怕的東西。 – sje397
「似乎工作正常」 - 是的,但*它是*? :P – Marlon
這會在Vista和Win7上很好地轟炸你的程序。時間溝XP。 –
@Marlon--這不完全是我的問題嗎? – sje397