2011-07-31 75 views
2

的代碼的運行時間檢測:記憶缺失

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作爲平臺。

我無法弄清楚爲什麼在第二種情況下會出現運行時錯誤?

回答

9

您的代碼引起未定義行爲。未定義的行爲意味着任何事情都可能發生,行爲不能被定義。該程序只是純粹的運氣,其行爲無法解釋。

基本上,

如果你與你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)

0

因爲你改變q點在什麼地址,然後試圖將其刪除。

您應該只有永遠嘗試delete無論new返回給你。其他任何東西都是未定義的行爲。

1

因爲你必須通過新的不變結果刪除。這就是事情的工作方式,即新/刪除的API合同。

3

有兩種錯誤的位置:

  1. 不能delete指針不是由new返回。
  2. 你不能delete,是由new[]返回一個指針 - 你需要使用delete[]

因此,第一個片段只能巧合使用,並且沒有錯誤只是因爲您使用的是原始類型。如果它是UDT,析構函數將不會運行。

此外,你應該使用,而不是生newdelete容器和智能指針。