2013-08-19 64 views
0

我的問題似乎微不足道的一些人,但我不明白爲什麼這樣的代碼:將零分配給指針會銷燬分配的內存嗎?

double * a = new double [3]; 
a[0] = 1; 
a[1] = 2; 
a[2] = 3; 

a = 0; 

for(int i=0; i<3;i++) 
cout << " a[" << i << "] = " << a[i] << endl; 

delete [] a ; 

沒有給出以下結果:

a[0] = 0; 
a[1] = 0; 
a[2] = 0; 
+5

你爲什麼認爲它會給這個結果? – Borgleader

+0

您正在索引空指針。如果你想給每個元素賦0,使用'std :: fill(_n)'。 – chris

+1

你只是改變指針指向的東西。首先,它指向一個數組,然後它指向無處。沒有什麼指向陣列了。 – juanchopanza

回答

7

new[]分配的原始內存泄漏。你現在有相當於

double * a = 0; //or NULL 

有內存泄漏。訪問空指針會給你未定義的行爲。不,將0分配給指針不會破壞內存。

+0

我想我明白我無法訪問任何東西NULL指針**,即使我之前分配的內存沒有被銷燬**。謝謝 – SAAD

1

將零賦值給一個指針不會破壞已分配的內存,該指針將指向該內存段。分配零後,delete[]不會刪除該部分內存。

2

您的代碼將崩潰和/或產生一些隨機結果(如果您將其他常量分配給a)。 爲什麼?

在你的代碼中,a是一個指向你自己使用的內存區域的指針(使用new)。所以你有一個值a0x05237484(只是一個隨機的例子)。所以,你知道通過這個地址0x05237484有24個字節(3 * 8,8是一個雙倍的大小)爲你保留的字節。 從本質上講,當你說new double[5]時,你對運行時所說的是: 「現在,找到一個足夠空間來存儲5個雙打數組,併爲我保留它,所以只有我可以使用它」。運行時爲您預留內存並將地址存儲在您提供的指針中 - a

然後,您所做的就是用其他值覆蓋指針a。這意味着內存仍然爲您保留(因爲您沒有通過使用deletedelete[]告訴運行時您不再需要它),但是您已經忘記了它的存儲位置。

相反,您的記錄現在指向一些其他內存位置 - 哪裏可以有任何內容。所以,要麼你會從你現在指向的地方得到一些隨機值(如果你碰巧最終在同一個進程內存中),你的程序會崩潰說「訪問衝突」 - 意味着你試圖訪問屬於另一個過程/系統/任何。 你在做什麼在這裏分配a = 0後,訪問3個地點:

a[0] // which is a+0 == 0x00000000 
a[1] // which is a+1 == 0x00000001 
a[2] // which is a+2 == 0x00000002 

你不會知道在那個位置是什麼 - 但嘗試它,你要麼打「拒絕訪問」錯誤,或者收到的隨機數據(屬於應用程序的其他部分)。

而且,更糟糕的是,你已經記住了一些內存給你,但沒有釋放它 - 這意味着你已經從計算機內存中吃掉了沒有。這就是所謂的'內存泄漏'

+0

不,它不應該崩潰 - 它只是泄漏內存。定義一個NULL指針的'delete'是安全的。設置'a = 17;'會導致未定義的行爲(潛在的崩潰)。用空指針刪除 –

+3

- 是的,但是閱讀怎麼樣? 「訪問衝突 - 從地址0x000000讀取」是在Win98天后的相當頻繁的錯誤:) – DarkWanderer

+0

啊,對不起,我同意。 –