C 堆還是棧上建立物件

2021-07-16 21:12:31 字數 2496 閱讀 6248

如果需要在堆上建立物件,要麼使用new運算子,要麼使用malloc系列函式。這點沒有異議。

真正有異議的是下面的**:

c++ 1

object

obj;

此時,obj是在棧上分配的嗎?

要回答這個問題,我們首先要理解這個語句是什麼意思。這個語句就是代表著,在棧上建立物件嗎?

其實,這行語句的含義是,使物件obj具有「自動儲存(automatic storage)」的性質。所謂「自動儲存」,意思是這個物件的儲存位置取決於其宣告所在的上下文。

如果這個語句出現在函式內部,那麼它就在棧上建立物件。

如果這個語句不是在函式內部,而是作為乙個類的成員變數,則取決於這個類的物件是如何分配的。考慮下面的**:

c++ 1

2

3

4

5

6

class

class

;

class

*pclass

=new

class

;

指標pclass所指向的物件在堆上分配空間。因為object obj;語句的含義是「自動儲存」,所以,pclass->obj也是在堆上建立的。

理解了這一點,再來看下面的語句:

c++ 1

2

object

*pobj

; pobj

=new

object

;

object *pobj;代表,指標pobj是自動儲存的,僅此而已,沒有任何其它含義。而下面一行語句則指出,這個指標所指向的物件是在堆上面分配的。如果這兩行語句出現在乙個函式內部,意味著當函式結束時,pobj會被銷毀,但是它指向的物件不會。因此,為了繼續使用這個物件,通常我們會在函式最後新增乙個return語句,或者使用乙個傳出引數。否則的話,這個在堆上建立的物件就沒有指標指向它,也就是說,這個物件造成了記憶體洩露。

並不是說指標指向的物件都是在堆上建立的。下面的**則使用指標指向乙個在棧上建立的物件:

c++ 1

2

object

obj;

object

*pobj

=&obj

;

至此,我們解釋了函式內部的變數和成員變數。還有兩類變數:全域性變數和static變數。它們即不在堆上建立,也不在棧上建立。它們有自己的記憶體空間,是除堆和棧以外的資料區。也就是說,當object obj即不在函式內部,又不是類的成員變數時,這個物件會在全域性資料段建立,同理適用於static變數。對於指標object *pobj;,如果這個語句出現在函式內部或類的成員變數,正如我們前面所說的,這個指標是自動儲存的。但是,如果這個語句是在類的外部,它就是在全域性資料段建立的。雖然它指向的物件可能在堆上建立,也可能在棧上建立。

堆和棧的區別在於兩點:

生命週期

效能但是,有些情況,即便你在棧上建立了物件,它還是會占用堆的空間。考慮如下**:

c++ 1

2

3

4

void

func

物件v是在棧上建立的。但是,stl 的vector類其實是在堆上面儲存資料的(這點可以檢視源**)。因此,只有物件v本身是在棧上的,它所管理的資料(這些資料大多數時候都會遠大於其本身的大小)還是儲存在堆上。

關於第二點效能,有影響,不過一般可以忽略不計。確切的說,一般情況下你不需要考慮效能問題,除非它真的是乙個問題。

首先,在堆上建立物件需要追蹤記憶體的可用區域。這個演算法是由作業系統提供,通常不會是常量時間的。當記憶體出現大量碎片,或者幾乎用到 100% 記憶體時,這個過程會變得更久。與此相比,棧分配是常量時間的。其次,棧的大小是固定的,並且遠小於堆的大小。所以,如果你需要分配很大的物件,或者很多很多小物件,一般而言,堆是更好的選擇。如果你分配的物件大小超出棧的大小,通常會丟擲乙個異常。儘管很罕見,但是有時候也的確會發生。有關效能方面的問題,更多出現在嵌入式開發中:頻繁地分配、釋放記憶體可能造成碎片問題。

現代作業系統中,堆和棧都可以對映到虛擬記憶體中。在 32 位 linux,我們可以把乙個 2g 的資料放入堆中,而在 mac os 中,棧可能會限制為 65m。

總的來說,關於究竟在堆上,還是在棧上建立物件,首要考慮你所需要的生命週期。當效能真正成為瓶頸的時候,才去考慮效能的問題。堆和棧是提供給開發者的兩個不同的工具,不存在乙個放之四海而皆準的規則告訴你,乙個物件必須放在堆中還是在棧中。選擇權在開發者手中,決定權在開發者的經驗中。

C 在堆上建立物件還是在棧上建立物件

對於 object obj obj是在棧上分配的嘛?其實,這個語句的含義是,使物件obj具有 自動儲存的性質 意思就是這個物件的儲存位置取決於其宣告所在的上下文。如果這個語句出現在函式內部,那麼它就在棧上建立物件。如果這個語句不是在函式內部,而是作為乙個類的成員變數,則取決於這個類的物件是如何分配的...

C 在堆上建立物件,還是在棧上?

如果需要在堆上建立物件,要麼使用new運算子,要麼使用malloc系列函式。這點沒有異議。真正有異議的是下面的 c 1 object obj 此時,obj是在棧上分配的嗎?要回答這個問題,我們首先要理解這個語句是什麼意思。這個語句就是代表著,在棧上建立物件嗎?其實,這行語句的含義是,使物件obj具有...

只能在堆或棧上建立物件?

1.只能在堆 heap 上建立物件 禁止產生棧 stack 物件 建立棧物件時會移動棧頂指標以 挪出 適當大小的空間,再在這個空間上直接呼叫對應的建構函式以形成乙個棧物件,而當函式返回時會呼叫其析構函式釋放這個物件,再調整棧頂指標收回那塊棧記憶體 在這個過程中是不需要operator new del...