2014-02-08 49 views
2

複製如何爲動態變量工作?爲什麼我們使用一個指針來初始化它們?動態內存拷貝如何工作?

int* a = new int; 
a = 5; 
int* b = new int; 
b = a; 
delete a; 

上面的代碼是做什麼的?

+1

你在問什麼?你想知道爲什麼你的代碼不能編譯? – juanchopanza

+0

什麼是動態變量?你爲什麼認爲它複製時的行爲有所不同? –

+0

你可以看看http://stackoverflow.com/questions/15151377/what-exactly-is-a-c-pointer-if-not-a-memory-address –

回答

3

分析:

線#1int* a = new int;

變量a被設置爲指向一塊動態分配的存儲器(典型地在堆)的。

2號線a = 5;

可變a設置爲指向,以解決5在內存中,所以你已經「丟失」的指針指向一塊內存以前分配,你將無法稍後釋放它(又稱內存泄漏)。

線#3int* b = new int;

b變量被設置爲指向一塊動態分配的存儲器(典型地在堆)的。

線路#4b = a;

b變量被設置以指向可變a指向,即,在存儲器地址5。所以再一次,你已經「丟失」了指向先前分配的那塊內存的指針,並且以後你將無法釋放它。

5號線delete a;

嘗試釋放以前分配的內存塊,位於地址5.這個嘗試很可能會導致程序崩潰,因爲一個內存訪問衝突,如delete操作保證只對先前調用相同類型的new操作返回的地址值成功完成。

爲了解決上述所有問題,你可以做到以下幾點:

  1. 變化a = 5*a = 5

  2. 變化b = a*b = *a

  3. delete a後添加delete b

作爲步驟2和3的替代方法,您可以簡單地將int* b = new int更改爲int* b

1

由線撕裂下來行:

int* a = new int; 

上分配的自由存儲區的int變量和a存儲其地址,其類型爲pointer to int

a = 5; 

你可能想要寫*a = 5;代替,這將值5int變量通過a指向。

int* b = new int; 

上分配的自由存儲有int變量和其地址存儲在b其類型爲pointer to int

b = a; 

你可能想要寫*b = *a;來代替,該分配int變量的值指向bint變量通過a指向。
b = a;讓b指向了同一個變量int所指向的a,你立即失去跟蹤int變量的最初指向b,這是一個內存泄漏。

delete a; 

解除分配int變量通過a指向。在這裏你也應該delete b;,否則就是內存泄漏。

我建議你在編寫任何實際代碼之前,從C/C++指針概念的最開始。

1

也許你想分配5到一個指向的地址:

*a = 5; 

然後你做

b = a; 

b爲指向一個指向相同的內存: 含5的​​一個。

當你

delete a; 

您釋放了a和b指向的內存。

在這一點上,你泄漏了最初由b指出的內存。作爲經驗法則,每一個新的匹配刪除。

但你可能要做到以下幾點:

int* a = new int; 
*a = 5; 
int* b = new int; 
*b = *a; 
delete a; 
delete b; 

這意味着你分配的內存*一個 然後分配5 *一, 分配爲* B的存儲,複製*一對* b 並釋放內存。

1

我們使用指針訪問堆上的內存 - 這是當函數返回時不會消失的內存。

b = a不會複製存儲器中的內容,而不是它叫:

1)創建的第二個堆內存是沒有再訪問

2)這兩個變量ab現在參考到第一行創建的相同內存。

delete a然後釋放該內存。它不應再被使用(ab現在指向你不應該使用的東西)。在第三行中分配的內存永遠不會被釋放(所以它被「泄漏」)。

1

你的代碼甚至沒有編譯,因爲你的第二行是錯誤的。這可能與某些編譯標誌工作壽

error: invalid conversion from 'int' to 'int*' 

你可能想要的是:

int* a = new int; 
*a = 5; 
int* b = new int; 
b = a; 
delete a; 

的指針這樣的想法:

Variable name | Memory address | Value 
1.st line 
a | 1000 | 2000 //pointer a at address 1000 points to address 2000 on heap 
/| 2000 |/ //int on address 2000 with undefined value 

2nd line 
/| 2000 | 5 //set the value at the memory pointed by a to 5 

3rd line 
b | 1004 | 2500 //another pointer pointing to another int on heap 
/| 2500 |/

4th line 
b | 1004 | 2000 //b now points to the address that a is pointing to 

5th line 
Deallocates memory at address 2000 

在4號線,你只是得到了內存泄漏,因爲你失去了指向你的第二個int的指針。

爲什麼要使用指針?因爲當你將變量傳遞給函數時,它們的值被複制,這可能是一個昂貴的操作。例如:

void func(HugeObject ho) { 
    //do something 
} 
main() { 
    HugeObject ho(); 
    func(ho); 
} 

整個HugeObject將被複制到函數中。由於這是很多內存,所以它的操作很昂貴。使用指針這不是問題:

void func(HugeObject * ho) { 
    //do something 
} 
main() { 
    HugeObject * ho = new HugeObject(); 
    func(ho); 
    delete ho; 
} 

如果我們使用指針,我們只複製32或64位地址,而不是整個對象。

一般來說,在你的代碼周圍傳遞int是一個壞主意,因爲你得到了指針的所有問題,沒有任何好處。事實上,在64位機器上,因爲int通常是32位,所以你會使用更多的內存來傳遞指針。我不是C++專家,所以如果我看到一個明顯的錯誤,請糾正我。我不想傳播任何錯誤信息。