棧和堆原理介紹

2022-02-10 02:21:25 字數 1868 閱讀 8644

c++應用中記憶體分為2部分,一部分是棧(stack,也稱堆疊),另一部分是堆(heap)。

棧:可以把棧看成是一疊卡片,最上面的卡片表示程式的當前作用域,這往往就是當前正在執行的函式。當前函式中宣告的所有變數都置於棧頂幀中,即占用棧頂幀的記憶體,這就相當於一疊卡片中最上面的一張卡片。如果當前函式呼叫了另乙個函式,舉例來說,一開始一疊卡片位於最底的卡片是main()函式,main()函式呼叫了foo()函式,則相當於在這一疊卡片上加了另一張卡片,這樣foo()函式就有了自己的棧幀(就是指一塊記憶體空間)以供使用。從main()傳遞到foo()的所有引數都會從main()棧幀複製到foo()棧幀中。 然後foo()函式又呼叫了bar()函式,則在這一疊卡片上又加了一張卡片,這樣bar()就有了自己的棧幀(stack frame)以供使用,從foo()傳遞到bar()的引數就會從foo()棧幀複製到bar()棧幀中。 如下: foo()函式宣告了乙個整數值。

棧幀很有意義,因為棧幀可以為每個函式提供乙個獨立的記憶體工作區。如果乙個變數是在foo()棧幀中宣告的,那麼呼叫bar()函式不會對它帶來改變,除非你專門要求修改這個變數。另外,foo()函式執行結束時,棧幀既消失,該函式中宣告的所有變數就不會再占用記憶體了。。

堆:堆是一段完全獨立於當前函式或棧幀的記憶體區。如果乙個函式中宣告了一些變數,而且希望當這個函式結束時其中宣告的變數依然存在,就可以將這些變數置於堆中。堆與棧相比,沒有那麼清晰的結構性。可以把堆看作是一「堆」小玩藝。程式可以在任何時刻向這個「堆」新增新的東西或者修改「堆」中已經有的東西。

用棧和堆來分析動態分配陣列的原理:根據棧的工作原理,編譯器在編譯時就必然能夠確定每個棧幀有多大。 由於棧幀大小是預定的,因此無法宣告乙個大小可變的陣列。 如: 以下**就無法通過編譯,因為arraysize是變數,而不是常量。

int arraysize = 8;

int myvaraiblesizedarray( arraysize );           // 不能通過編譯

由於整個陣列都要放在棧上,編譯器需要準確地知道陣列的大小(根據棧的工作原理,編譯器在編譯時必須要確定每個棧幀有多大。)所以不充許用變數來指定陣列大小,如果通過使用動態記憶體(dynamic memory),把陣列放在堆中(而不是棧中),就可以在執行時才指定陣列的大小。

要動態分配乙個陣列,首先需要宣告乙個指標(pointer):

int * myvariablesizedarray;

myvariablesizearray = new int[arraysize];        // 在堆中分配陣列空間

這就會根據arraysize變數的大小來分配相應的記憶體。可以看到,指標變數任然位於棧中,而指標指向的陣列則位於堆中。。

然而由於堆中變數占用的記憶體空間不會因為程式或函式結束而釋放掉(在棧中變數則會因為程式或函式結束而釋放記憶體),因此就需要人工來釋放掉堆中的記憶體。用delete命令來釋放記憶體.

delete  myvariablesizearray;

介紹堆與棧

首先在資料結構上要知道堆疊,儘管我們這麼稱呼它,但實際上堆疊是兩種資料結構 堆和棧。我們先從大家比較熟悉的棧說起吧,它是一種具有後進先出性質的資料結構,也就是說後存放的先取,先存放的後取。這就如同我們要取出放在箱子裡面底下的東西 放入的比較早的物體 我們首先要移開壓在它上面的物體 放入的比較晚的物體...

關於堆和棧

1 記憶體分配方面 堆 一般由程式設計師分配釋放,若程式設計師不釋放,程式結束時可能由os 注意它與資料結構中的堆是兩回事,分配方式是類似於鍊錶。可能用到的關鍵字如下 new malloc delete free等等。棧 由編譯器 compiler 自動分配釋放,存放函式的引數值,區域性變數的值等。...

關於堆和棧

網上找到的,有什麼不對的大家指出來,重新學習 1.棧是存放函式返回位址 引數 區域性變數的。堆是程式可以自由操作的記憶體,使用時先申請,用完之後釋放,如何使用完全由程式 控制。2.棧在彙編 中表示成push pop,用的是ess段,sp暫存器 而堆不是,是在記憶體中讀寫,eds段,3.c 包括兩種被...