複製如何爲動態變量工作?爲什麼我們使用一個指針來初始化它們?動態內存拷貝如何工作?
int* a = new int;
a = 5;
int* b = new int;
b = a;
delete a;
上面的代碼是做什麼的?
複製如何爲動態變量工作?爲什麼我們使用一個指針來初始化它們?動態內存拷貝如何工作?
int* a = new int;
a = 5;
int* b = new int;
b = a;
delete a;
上面的代碼是做什麼的?
分析:
線#1:int* a = new int;
變量a
被設置爲指向一塊動態分配的存儲器(典型地在堆)的。
2號線:a = 5;
可變a
設置爲指向,以解決5在內存中,所以你已經「丟失」的指針指向一塊內存以前分配,你將無法稍後釋放它(又稱內存泄漏)。
線#3:int* b = new int;
b
變量被設置爲指向一塊動態分配的存儲器(典型地在堆)的。
線路#4:b = a;
b
變量被設置以指向可變a
指向,即,在存儲器地址5。所以再一次,你已經「丟失」了指向先前分配的那塊內存的指針,並且以後你將無法釋放它。
5號線:delete a;
嘗試釋放以前分配的內存塊,位於地址5.這個嘗試很可能會導致程序崩潰,因爲一個內存訪問衝突,如delete
操作保證只對先前調用相同類型的new
操作返回的地址值成功完成。
爲了解決上述所有問題,你可以做到以下幾點:
變化a = 5
到*a = 5
變化b = a
到*b = *a
delete a
後添加delete b
作爲步驟2和3的替代方法,您可以簡單地將int* b = new int
更改爲int* b
。
由線撕裂下來行:
int* a = new int;
上分配的自由存儲區的int
變量和a
存儲其地址,其類型爲pointer to int
。
a = 5;
你可能想要寫*a = 5;
代替,這將值5
到int
變量通過a
指向。
int* b = new int;
上分配的自由存儲有int
變量和其地址存儲在b
其類型爲pointer to int
。
b = a;
你可能想要寫*b = *a;
來代替,該分配int
變量的值指向b
到int
變量通過a
指向。
b = a;
讓b指向了同一個變量int
所指向的a
,你立即失去跟蹤int
變量的最初指向b
,這是一個內存泄漏。
delete a;
解除分配int
變量通過a
指向。在這裏你也應該delete b;
,否則就是內存泄漏。
我建議你在編寫任何實際代碼之前,從C/C++指針概念的最開始。
也許你想分配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 並釋放內存。
我們使用指針訪問堆上的內存 - 這是當函數返回時不會消失的內存。
您b = a
不會複製存儲器中的內容,而不是它叫:
1)創建的第二個堆內存是沒有再訪問
2)這兩個變量a
和b
現在參考到第一行創建的相同內存。
delete a
然後釋放該內存。它不應再被使用(a
和b
現在指向你不應該使用的東西)。在第三行中分配的內存永遠不會被釋放(所以它被「泄漏」)。
你的代碼甚至沒有編譯,因爲你的第二行是錯誤的。這可能與某些編譯標誌工作壽
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++專家,所以如果我看到一個明顯的錯誤,請糾正我。我不想傳播任何錯誤信息。
你在問什麼?你想知道爲什麼你的代碼不能編譯? – juanchopanza
什麼是動態變量?你爲什麼認爲它複製時的行爲有所不同? –
你可以看看http://stackoverflow.com/questions/15151377/what-exactly-is-a-c-pointer-if-not-a-memory-address –