首先我們來認識一下堆與棧的含義():
(1)棧區(stack):由編譯器自動分配和釋放,存放函式的引數值、區域性變數的值等,其操作方式類似於資料結構中的棧。
(2)堆區(heap):一般由程式設計師分配和釋放,若程式設計師不釋放,程式結束時可能由作業系統**。分配方式類似於資料結構中的鍊錶。
(3)全域性區(靜態區)(static):全域性變數和靜態變數的儲存是放在一塊的,初始化的全域性變數和靜態變數在一塊區域,未初始化的全域性變數和未初始化的靜態變數在相鄰的另一塊區域。程式結束後由系統自動釋放。
(4)文字常量區:常量字串就是存放在這裡的。
(5)程式**區:存放函式體的二進位制**。
解釋的名詞有點多了,但這不是重點,重點是看例子!
例子對上面的名詞有了充分的解釋。
所以堆和棧的區別:
stack的空間由作業系統自動分配/釋放,heap上的空間手動分配/釋放。
stack的空間有限,heap是很大的自由儲存區。
程式在編譯期和函式分配記憶體都是在棧上進行,且程式執行中函式呼叫時引數的傳遞也是在棧上進行。
為了更好的了解這些東西,我們來檢視,map檔案中的內容。
找到相關的有用資訊
顯然__initial_sp是堆疊指標他就是flash的0x8000000位址的前面4個位元組(他根據堆疊大小有便器自動生成)
從中可以看出對於heap堆的起始位址(base addr)是0x200000a8,佔0x200,所以stack棧的起始位址(base addr)是0x200002a8.
顯然堆與棧是相鄰的。以乙個圖來說明(沒錯,這是別人做的圖,,,,)
堆和棧空間分配
棧:向低位址擴充套件 0x200006a8---------->0x200002a8
堆:向高位址擴充套件 0x200000a8---------->0x200002a8
堆和棧變數
棧:臨時變數,退出該作用域就會自動釋放
堆:malloc變數,通過free函式釋放
另外:堆疊溢位,編譯不會提示,需要注意
看到比較有意思的別人關於堆與棧的解釋(好吧,就當複習一下上面的介紹)
棧:存函式的臨時變數,即區域性變數,函式返回時隨時有可能被其他函式棧用。所以棧是一種分時輪流使用的儲存區,編譯器裡定義的stack_size,是為了限定函式的區域性資料活動的範圍,操過這麼範圍有可以跑飛,也就是棧溢位;stack_size不影響hex,更不影響hex怎麼執行的,只是在debug除錯時會提示錯。棧溢位也有是超過了國界進行活動,只要老外沒有意見,你可以接著玩,有老外不讓你玩,你就的得死,或是大家都死(互相撕殺),有的人寫微控制器**在函式裡定義乙個大陣列 int buf[8192],棧要是小於8192是會死的很慘。
堆:存的是全域性變數,這變數理論上是所有函式都可以訪問的,全域性變數有的有初始值,但這個值不是存在
ram裡的,是存在
hexflash
裡,上電由**(編譯器生成的彙編**)搬過去的。
有的人很「霸道」,上電就霸佔已一塊很大的
ram(
heap_size
),作為己有
(malloc_init)
,別人用只能通過他們管家借
(malloc)
,用完還得換
(free)
。所以一旦有「霸道」的人出現是編譯器裡必須定義
heap_size
,否則和他管家借也沒有用。、
參考:
1、2、
STM32學習堆和棧(三)
可程式設計內存在基本上分為這樣的幾大部分 靜態儲存區 堆區和棧區。他們的功能不同,對他們使用方式也就不同。靜態儲存區 內存在程式編譯的時候就已經分配好,這塊內存在程式的整個執行期間都存在。它主要存放靜態資料 全域性資料和常量。棧區 在執行函式時,函式內區域性變數的儲存單元都可以在棧上建立,函式執行結...
關於STM32堆疊方面知識點
最近弄json,發現經常的堆溢位,然後找問題。因為對stm32堆疊問題沒有深刻認識,就花時間好好研究下了堆疊並且做了驗證 1.棧位址區間確定 首先找到啟動檔案,我的啟動檔案在startup stm32f40xx.s,一般的啟動檔案也都在startup stm32f x.s檔案裡 initial sp...
STM32休眠與喚醒
這兩天研究了stm32的低功耗知識,低功耗裡主要研究的是stm32的待機模式和停機模式 讓微控制器進入的待機模式和停機模式比較容易,實驗中通過設定中斷口pa1來響應待機和停機模式。voidexti1 irqhandler void void standby 進入的待機模式和停機模式很簡單,基本一樣。...