2012-05-30 21 views
3

我有點困惑時,我只是聲明一個變量,如之間的區別:聲明一個變量vs動態分配內存給C++中的一個變量?

int n; 

,並使用動態分配的內存變量「新」,如:

int m = new int; 

我只是從一個簡單的鏈接列表項目中注意到,當我以節點對象的形式插入一個新值時,我必須動態創建一個新節點對象並將所需值附加到它然後將其鏈接到其他節點對象我的名單。然而..在同一個函數中,我可以定義另一個節點對象,例如。 NodeType * N。並使用這個指針遍歷我的列表。 我的問題是,當我們只聲明一個變量,內存是不是立即分配..或有什麼區別?

謝謝!

+1

我[以前回答過](http://stackoverflow.com/questions/8839943/why-does-the-use-of-new-cause-memory-leaks-in-c/8840302#8840302)。 –

+3

區別?一個工程,另一個給你一個編譯器錯誤。 ('int *'不能隱式轉換爲'int'。) – cHao

+2

@ R.MartinhoFernandes這似乎是一個不同的問題。 – Pubby

回答

5

不想自動分配存儲空間的變量時可能:

int n; 

over

int* m = new int; // note pointer 

動態分配的原因最好在你的情況就是定義鏈表的方式。即每個節點都包含一個指向下一個節點的指針(可能)。由於節點必須存在於創建點之外,因此它們將被動態分配。

NodeType * N。並使用這個指針遍歷我的列表

是的,你可以這樣做。但請注意,這只是一個指針聲明。您必須將其分配給實際使用它的內容。

我的問題是..當我們只是聲明一個變量,內存是不是立即分配..或有什麼區別?

實際上,兩種情況都是定義,而不僅僅是聲明。

int n; 

創建一個未初始化的帶有自動存儲的int;

int* n; 

創建的指針int。它懸而未決,它不指向有效的內存位置。

int* n = new int; 

創建一個指針並將其初始化爲含有一個未初始化的int一個有效的內存位置。

int* n = new int(); 

創建一個指針並將其初始化爲包含有效存儲器位置的值初始化int(即0)。

+0

+1非常豐富。總是很高興看到你的答案,Luchian。 – Drise

1
int m = new int; 

實際上是不正確的。 new返回一個指向其創建的內存的指針。它應該是

int *m = new int; 

更妙的是:

int *m = new int(); 

其設置變量的初始值指向M = 0

此外,關於你的問題,大對象通常是用指針創建的,當它們從函數傳遞到函數時,消除大的複製操作。當變量的使用時間需要比函數的範圍更長時,也可以使用它們。

然而,對於一個函數的範圍使用的變量,而不是有用的其他地方,自動內存應使用

int m; 
+2

「另外,關於您的問題,通常會使用指針創建大對象,以在從函數傳遞到函數時消除大型複製操作。」這是不正確的,你可以通過引用傳遞。有不同的原因。 –

+1

我通常不會傳遞指針,除非我交出對象的「所有權」。 (即使如此,它通常是一個智能指針類型。)對於其他任何情況,在處理我自己的代碼時,我都會通過引用傳遞。除了明確地「不是你的」語義(無論如何),並且讓它更難以無意間鬆開一個隨時可能變得無效的指針,它還會使得代碼不會與'*'和' - >'和' &'。 – cHao

+0

毫米,只是另一個快速問題。通過引用傳遞意味着什麼?我猜這不同於像(*頭,**列表等)指針傳遞? – jerbotron

1

不同之處在於,自動存儲只能在編譯器可以在編譯時確定需要多少內存以及需要多長時間時才能使用。通常自動變量將分配在stack上。

對於動態分配的內存,程序員負責跟蹤這些信息。這通常分配在堆上。由於各種原因,使用堆內存通常會產生更大的開銷,並且存在分配堆內存但從不釋放內存的內存泄漏風險。

在你描述鏈表的例子中,你不太可能在編譯時知道列表的長度(如果你這樣做了,那麼你可以使用靜態數組),所以這就是爲什麼你需要管理內存顯式而不是讓編譯器自動處理內存管理。但是在函數返回後,用於遍歷列表的指針並不是必需的,所以這就是編譯器可以自動管理它的原因。

相關問題