的代碼的運行時間檢測:記憶缺失
int *ptr = new int[10];
int *q = ptr;
delete q;
沒有任何問題(沒有運行時錯誤)工作正常。
但是,下面的代碼:
int *ptr = new int[10];
int *q = ptr;
q++;
delete q;
導致運行時錯誤。
我正在使用Microsoft Visual Studio-8和Win-7作爲平臺。
我無法弄清楚爲什麼在第二種情況下會出現運行時錯誤?
的代碼的運行時間檢測:記憶缺失
int *ptr = new int[10];
int *q = ptr;
delete q;
沒有任何問題(沒有運行時錯誤)工作正常。
但是,下面的代碼:
int *ptr = new int[10];
int *q = ptr;
q++;
delete q;
導致運行時錯誤。
我正在使用Microsoft Visual Studio-8和Win-7作爲平臺。
我無法弄清楚爲什麼在第二種情況下會出現運行時錯誤?
您的代碼引起未定義行爲。未定義的行爲意味着任何事情都可能發生,行爲不能被定義。該程序只是純粹的運氣,其行爲無法解釋。
基本上,
如果你與你new
MUST 使用分配delete
動態內存釋放它。
如果您正在使用new[]
分配動態內存,您需要必須使用delete[]
來取消分配它。
這是不確定的行爲的任何地址傳遞給它完全不會受到new
返回delete
。
以下是標準報價。根據C++ 03標準§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&)
返回的值。
在C++中,最好通過使用智能指針代替原始指針,它可以自動取存儲器解除分配的護理用RAII(SBRM)。
因爲你改變q
點在什麼地址,然後試圖將其刪除。
您應該只有永遠嘗試delete
無論new
返回給你。其他任何東西都是未定義的行爲。
因爲你必須通過新的不變結果刪除。這就是事情的工作方式,即新/刪除的API合同。
有兩種錯誤的位置:
delete
指針不是由new
返回。delete
,是由new[]
返回一個指針 - 你需要使用delete[]
。因此,第一個片段只能巧合使用,並且沒有錯誤只是因爲您使用的是原始類型。如果它是UDT,析構函數將不會運行。
此外,你應該使用,而不是生new
和delete
容器和智能指針。