2012-04-14 181 views
32

下面的代碼創建在棧上的對象:堆棧/堆上的對象創建?

Object o; 

當創建在堆上對象,就可以使用:

Object* o; 

o = new Object(); 

而非:

Object* o = new Object(); 

當我們分裂在兩行創建堆對象並在第二行調用構造函數(o = new object()),這是否意味着在第一行(Object* o)指針是在堆棧上創建的?因此Object o將對象放在堆棧上,而Object* o將指針放在堆棧上的未來對象上?

我的第二個問題涉及如果兩行代碼被稱爲類之外。我最近閱讀(Global memory management in C in stack or heap?)全局變量不包含在堆棧/堆中,但實際上是另一部分內存?如果是這樣的話,Object* o會創建一個指針,該指針位於內存的另一部分,並指向堆對象?

+0

這兩個將*大概*優化,以同樣的事情,我想。 – Ryan 2012-04-14 20:33:57

+15

_pointer_始終在堆棧上創建。 – leftaroundabout 2012-04-14 20:36:41

+1

我會第二@leftaroundabout,並走得更遠:在一個塊中聲明的所有變量都在棧上創建的;第一個示例的整個對象以及第二個對象的指針。 – 2012-04-14 20:50:39

回答

72

其實,無論聲明說,大約堆或疊東西:

Object o; 

創建了自動存儲意味着存儲位置由對象所聲明的環境確定的對象:如果代碼在函數中,這恰好是調用堆棧。但是該行也可以是類成員,或者如您所知,除了函數/類之外。

爲了說明爲什麼這是不同的:

struct Foo { 
    Object o; 
}; 

Foo* pf = new Foo(); 

現在對象pf->o創建在堆上,而不是在堆棧中,即使(或更確切地說,因爲)它具有自動存儲。

相反,

Object* p; 

只是聲明瞭一個指針,僅此而已。所述指針的存儲是從任何其他對象的不可區分的:它具有自動存儲。此外,初始化表達式對變量存儲沒有影響。

什麼指針所指向的是一個完全不同的事情。它可能是一個堆分配的對象(例如使用new),或者它可能指向另一個自動分配的對象。試想一下:

Object o; 
Object* p = &o; 
+1

你能解釋一下「自動存儲」是什麼意思嗎?另外,Foo pf = new Foo()會有什麼區別?和Foo * pf = new Foo(); ? – user997112 2012-04-14 20:53:04

+8

Foo pf = new Foo()會有什麼區別?和Foo * pf = new Foo(); - 第二個會編譯,而第一個不會? – dasblinkenlight 2012-04-14 20:58:34

+0

因爲我們只能使用關於堆分配的指針嗎? – user997112 2012-04-14 21:04:38

3

這兩種形式是相同的,只有一個例外:臨時,新的(Object *)具有未定義的值,當創建和分配是分開的。編譯器可能會將它們組合在一起,因爲未定義的指針不是特別有用。這不涉及全局變量(除非聲明是全局的,在這種情況下,對於這兩種形式都是如此)。

1

在這兩個示例中,Object*類型的局部變量都分配在堆棧上。如果程序沒有辦法檢測到差異,編譯器可以自由地從這兩個代碼片段生成相同的代碼。

全局變量的內存區域與靜態變量的內存區域相同 - 它既不在堆棧中,也不在堆中。您可以通過在函數中聲明static來在該區域中放置變量。這樣做的結果是,在您的函數的併發調用中,實例變爲共享,因此在使用靜態時需要仔細考慮同步。

這裏是a link來討論正在運行的C程序的內存佈局。

1

A)

Object* o; 
o = new Object(); 

`` B)

Object* o = new Object(); 

我覺得A和B具有無差異。在這兩種情況下,o都是指向Object類的指針。語句new Object()從堆內存中創建Object類的對象。賦值語句將分配的內存地址分配給指針o。

有一兩件事我想提一提從堆中分配的內存是大小始終的sizeof(對象)不是的sizeof(對象)+的sizeof(void *的)。

6

C++提供了三種不同的方法來創建對象:

  1. 基於堆棧如臨時對象
  2. 基於堆利用
  3. 靜態內存分配,如全局變量和namespace-適用範圍對象

考慮你的情況,

Object* o; 
o = new Object(); 

和:

Object* o = new Object(); 

這兩種形式是相同的。這意味着,一個指針變量o是在堆棧上創建的(假設的變量不屬於類別3以上)和其指向在堆,它包含對象的存儲器。