三種記憶體物件的比較

2021-09-20 03:01:58 字數 1476 閱讀 2299

c++將記憶體劃分為三個邏輯區域:堆、棧和靜態儲存區。既然如此,我稱位於它們之中的物件分別為堆物件,棧物件以及靜態物件。三種記憶體物件的比較

棧物件的優勢是在適當的時候自動生成,又在適當的時候自動銷毀,不需要程式設計師操心;而且棧物件的建立速度一般較堆物件快,因為分配堆物件時,會呼叫operator new操作,operator new會採用某種記憶體空間搜尋演算法,而該搜尋過程可能是很費時間的,產生棧物件則沒有這麼麻煩,它僅僅需要移動棧頂指標就可以了。但是要注意的是,通常棧空間容量比較小,一般是1mb~2mb,所以體積比較大的物件不適合在棧中分配。特別要注意遞迴函式中最好不要使用棧物件,因為隨著遞迴呼叫深度的增加,所需的棧空間也會線性增加,當所需棧空間不夠時,便會導致棧溢位,這樣就會產生執行時錯誤。

棧物件會在什麼會自動釋放了?第一,在其生命期結束的時候;第二,在其所在的函式發生異常的時候。

堆物件,其產生時刻和銷毀時刻都要程式設計師精確定義,也就是說,程式設計師對堆物件的生命具有完全的控制權。我們常常需要這樣的物件,比如,我們需要建立乙個物件,能夠被多個函式所訪問,但是又不想使其成為全域性的,那麼這個時候建立乙個堆物件無疑是良好的選擇,然後在各個函式之間傳遞這個堆物件的指標,便可以實現對該物件的共享。另外,相比於棧空間,堆的容量要大得多。實際上,當物理記憶體不夠時,如果這時還需要生成新的堆物件,通常不會產生執行時錯誤,而是系統會使用虛擬記憶體來擴充套件實際的物理記憶體。

接下來看看static物件

首先是全域性物件。全域性物件為類間通訊和函式間通訊提供了一種最簡單的方式,雖然這種方式並不優雅。一般而言,在完全的物件導向語言中,是不存在全域性物件的,比如c#,因為全域性物件意味著不安全和高耦合,在程式中過多地使用全域性物件將大大降低程式的健壯性、穩定性、可維護性和可復用性。c++也完全可以剔除全域性物件,但是最終沒有,我想原因之一是為了相容c。

其次是類的靜態成員,上面已經提到,基類及其派生類的所有物件都共享這個靜態成員物件,所以當需要在這些class之間或這些class objects之間進行資料共享或通訊時,這樣的靜態成員無疑是很好的選擇。

接著是靜態區域性物件,主要可用於儲存該物件所在函式被屢次呼叫期間的中間狀態,其中乙個最顯著的例子就是遞迴函式,我們都知道遞迴函式是自己呼叫自己的函式,如果在遞迴函式中定義乙個nonstatic區域性物件,那麼當遞迴次數相當大時,所產生的開銷也是巨大的。這是因為nonstatic區域性物件是棧物件,每遞迴呼叫一次,就會產生乙個這樣的物件,每返回一次,就會釋放這個物件,而且,這樣的物件只侷限於當前呼叫層,對於更深入的巢狀層和更淺露的外層,都是不可見的。每個層都有自己的區域性物件和引數。

在遞迴函式設計中,可以使用static物件替代nonstatic區域性物件(即棧物件),這不僅可以減少每次遞迴呼叫和返回時產生和釋放nonstatic物件的開銷,而且static物件還可以儲存遞迴呼叫的中間狀態,並且可為各個呼叫層所訪問。

C 三種記憶體物件比較

摘自 c 將記憶體劃分為三個邏輯區域 堆 棧和靜態儲存區。既然如此,我稱位於它們之中的物件分別為堆物件,棧物件以及靜態物件。三種記憶體物件的比較 棧物件的優勢是在適當的時候自動生成,又在適當的時候自動銷毀,不需要程式設計師操心 而且棧物件的建立速度一般較堆物件快,因為分配堆物件時,會呼叫operat...

三種 Statement 物件的比較

1 statement 物件 用於執行不帶引數的簡單 sql 語句 它提供了三種執行 sql語句的方法 executequery 用於產生單個結果集的 sql,如 select語句 executeupdate 用於執行 insert delete update create table drop t...

三種迴圈的比較

switch case 語法 switch 表示式 變數 case 值1 語句1 break case 值2 語句2 break default 語句3 break 執行過程 當程式執行到switch 表示式 變數 先判斷括號裡的表示式,執行大括號裡的case 後面的值1 如果和值1匹配,就執行語句...