由c/C++編譯的程序占用的內存分為以下幾個部分
1、棧區(stack)—由編譯器自動分配釋放,存放函數的參數值,局部變量的值等。其操作方式類似于數據結構中的棧。
2、堆區(heap)—一般由程序員分配釋放,若程序員不釋放,程序結束時可能由OS回收。注意它與數據結構中的堆是兩回事,分配方式倒是類似于鏈表,呵呵。
3、全局區(靜態區)(static)—,全局變量和靜態變量的存儲是放在一塊的,初始化的全局變量和靜態變量在一塊區域,未初始化的全局變量和未初始化的靜態變量在相鄰的另一塊區域。-程序結束后有系統釋放
4、文字常量區—常量字符串就是放在這里的。程序結束后由系統釋放
5、程序代碼區—存放函數體的二進制代碼。
STM32的地址空間映射圖
我們可以看到代碼存儲區域在CODE區域;
STM32的堆棧是存放在片上靜態SRAM中的,地址分配可以見Keil的編譯map文件:
代碼來源地址:https://download.csdn.net/download/emoeror_zhang/11286638
HEAP0x20000148Section512startup_stm32f10x_hd.o(HEAP)
STACK0x20000348Section1024startup_stm32f10x_hd.o(STACK)
__initial_sp0x20000748Data0startup_stm32f10x_hd.o(STACK)
上面節選中,HEAP是堆的基地址,__initial_sp是棧指針。示意圖如下
堆棧地址的設置
在上述圖和map中,我么可以看到堆的大小是0線0x200,也就是在0x20000148-0x20000348之間,而棧的地址大小是0x400,也就是在0x20000348-0x20000748。為什么他們的大小是這樣的,是怎么由來的呢?
打開匯編文件startup_stm32f10x_hd.s,我們可以找到相對應的設置堆棧大小的程序,如圖:
堆和棧,一般堆是由低地址往上增長,棧是由往下減少。都是連續的,C語言不提供內存保護機制類似的功能,如果堆一直增長,棧一直申請,然后就會導致棧溢出,從而導致程序崩潰。
變量儲存位置分析
同樣的,我們還是以上述的map文件為例子進行分析。
如圖所示,fac_ms和fac_us在程序中是static變量類型,儲存在0x20000000-0x20000148之間的位置,fac_ms在0x20000016,fac_us在0x20000014,那其他的地址處是什么數據呢?
繼續在map里面尋找,找到如下圖所示:
發現其余的地質處儲存了全局變量數組,以及引用的庫文件的全局變量。
在map里面我們看到,全局變量和靜態變量儲存的位置,和堆棧無關,那么堆棧儲存的內容是什么呢?
五、堆棧存放內容
1、棧區
存放函數的參數值,局部變量的值等等臨時變量,退出該作用域該臨時變量就會自動釋放。
2、堆區
系統會給每個程序分配一部分棧空間讓他們能夠運行起來,問題就是棧空間必然存在不夠用的問題,而堆不屬于程序,堆是獨立的,是公用的。只要你malloc(sizeof(SIZE_YOU_WANT)),就可以得到相應一部分的堆空間。
簡單的來說,就是當你使用的時候malloc申請一部分空間來使用,但是別忘記了使用完成之后free掉,不然往往會堆溢出,占用了棧的位置空間,導致程序奔潰。
總結:
如果我們設置了堆的空間大小,但是我們程序中沒有進行malloc申請,那么在程序事假運行的時候,我們棧的空間超過本身設置的空間,進入到堆里面,那么程序是不會出錯的,但是超過了堆的空間了,進入到全局變量區域,就會出現莫名其妙的錯誤。
不使用malloc,我們可以將堆設置成0,這是沒有問題的,但是棧的空間大小要設置成合適的,不然就會因為棧溢出,進入harderror,程序奔潰。
-
sram
+關注
關注
6文章
768瀏覽量
114869 -
STM32
+關注
關注
2272文章
10923瀏覽量
357427
發布評論請先 登錄
相關推薦
評論