一、C語言內存分區(qū)
C語言內存分區(qū)示意圖如下:
1. 棧區(qū)
棧區(qū)介紹
棧區(qū)由編譯器自動分配釋放,由操作系統(tǒng)自動管理,無須手動管理。
棧區(qū)上的內容只在函數(shù)范圍內存在,當函數(shù)運行結束,這些內容也會自動被銷毀。
棧區(qū)按內存地址由高到低方向生長,其最大大小由編譯時確定,速度快,但自由性差,最大空間不大。
棧區(qū)是先進后出原則,即先進去的被堵在屋里的最里面,后進去的在門口,釋放的時候門口的先出去。
存放內容
臨時創(chuàng)建的局部變量和const定義的局部變量存放在棧區(qū)。
函數(shù)調用和返回時,其入口參數(shù)和返回值存放在棧區(qū)。
2. 堆區(qū)
堆區(qū)介紹
堆區(qū)由程序員分配內存和釋放。
堆區(qū)按內存地址由低到高方向生長,其大小由系統(tǒng)內存/虛擬內存上限決定,速度較慢,但自由性大,可用空間大。
調用函數(shù)
用malloc等函數(shù)實現(xiàn)動態(tài)分布內存。
void *malloc(size_t);
參數(shù)size_t是分配的字節(jié)大小。
返回值是一個void*型的指針,該指針指向分配空間的首地址。
(void *型指針可以任意轉換為其他類型的指針)
用free函數(shù)進行內存釋放,否則會造成內存泄漏。
void free(void * /*ptr*/);
參數(shù)是開辟的內存的首地址。
3. 全局(靜態(tài))區(qū)
全局(靜態(tài))區(qū)介紹
通常是用于那些在編譯期間就能確定存儲大小的變量的存儲區(qū),但它用于的是在整個程序運行期間都可見的全局變量和靜態(tài)變量。
全局區(qū)有.bss段和.data段組成,可讀可寫。
.bss段
未初始化的全局變量和未初始化的靜態(tài)變量存放在.bss段。
初始化為0的全局變量和初始化為0的靜態(tài)變量存放在.bss段。
.bss段不占用可執(zhí)行文件空間,其內容由操作系統(tǒng)初始化。
.data段
已初始化的全局變量存放在.data段。
已初始化的靜態(tài)變量存放在.data段。
.data段占用可執(zhí)行文件空間,其內容有程序初始化。
4. 常量區(qū)
字符串、數(shù)字等常量存放在常量區(qū)。
const修飾的全局變量存放在常量區(qū)。
程序運行期間,常量區(qū)的內容不可以被修改。
5. 代碼區(qū)
程序執(zhí)行代碼存放在代碼區(qū),其值不能修改(若修改則會出現(xiàn)錯誤)。
字符串常量和define定義的常量也有可能存放在代碼區(qū)。
二、STM32存儲器分配
1. 隨機存儲器—RAM
RAM是與CPU直接交換數(shù)據(jù)的內部存儲器,也叫主存(內存)。
它可以隨時讀寫,而且速度很快,通常作為操作系統(tǒng)或其他正在運行中的程序的臨時數(shù)據(jù)存儲媒介。
當電源關閉時RAM不能保留數(shù)據(jù)(掉電數(shù)據(jù)消失哦)如果需要保存數(shù)據(jù),就必須把它們寫入一個長期的存儲設備中(例如硬盤)。
2. 只讀存儲器—ROM
ROM所存數(shù)據(jù),一般是裝入整機前事先寫好的,整機工作過程中只能讀出,而不像隨機存儲器那樣能快速地、方便地加以改寫。
ROM所存數(shù)據(jù)穩(wěn)定,斷電后所存數(shù)據(jù)也不會改變。
本文使用是STM32F103芯片,keil V5環(huán)境下默認的內存配置見下圖:
ROM區(qū)域是0x8000000開始,大小是0x10000,這片區(qū)域是只讀區(qū)域,不可修改,存放代碼區(qū)和常量區(qū)。
RAM區(qū)域是0x20000000開始,大小是0x5000,這片區(qū)域是可讀寫區(qū)域,存放的是全局(靜態(tài))區(qū)、堆區(qū)和棧區(qū)。
該芯片的內部分區(qū)如下圖所示:
三、基于STM32代碼驗證
1. 詳細代碼如下
#include "main.h" #include審核編輯:黃飛//用于字符串處理 #include //用于printf打印 #include //用于分配堆區(qū)---調用malloc和free #include "delay.h" #include "uart3.h" #include "led.h" //全局區(qū) int q1;//未初始化全局變量 static int q2;//未初始化靜態(tài)變量 const int q3;//未初始化只讀變量 int m1=1;//已初始化全局變量 static int m2=2;//已初始化靜態(tài)變量 //常量區(qū) const int m3=3;//已初始化只讀變量 int main(void) { SystemCoreClockUpdate(); //設置系統(tǒng)時鐘為72M LED_GPIO_Config(); Uart3_init(); while(1) { //棧區(qū) int mq1;//未初始化局部變量 int *mq2;//未初始化局部指針變量 int mq3=3;//已初始化局部變量 char qq[10] = "hello"; //已初始化局部數(shù)組 const int mq4;//未初始化局部只讀變量 const int mq5=3;//已初始化局部只讀變量 //堆區(qū) int *p1 = malloc(4); //已初始化局部指針變量p1 int *p2 = malloc(4); //已初始化局部指針變量p2 //全局區(qū) static int mp1;//未初始化局部靜態(tài)變量 static int mp2=2;//已初始化局部靜態(tài)變量 //常量區(qū) char *vv = "I LOVE YOU";//已初始化局部指針變量 char *mq = "5201314"; printf(" 棧區(qū)-變量地址 "); printf("未初始化局部變量 :0x%p ",&mq1); printf("未初始化局部指針變量:0x%p ",&mq2); printf("已初始化局部變量:0x%p ",&mq3); printf("已初始化局部數(shù)組:0x%p ", qq ); printf("未初始化局部只讀變量 :0x%p ",&mq4); printf("已初始化局部只讀變量:0x%p ",&mq5); printf(" 堆區(qū)-動態(tài)申請地址 "); printf("已初始化局部int型指針變量p1 :0x%p ", p1); printf("已初始化局部int型指針變量p2 :0x%p ", p2); printf(" 全局區(qū)-變量地址 "); printf("未初始化全局變量 :0x%p ",&q1); printf("未初始化靜態(tài)變量:0x%p ",&q2); printf("未初始化只讀變量:0x%p ",&q3); printf("已初始化全局變量 :0x%p ",&m1); printf("已初始化靜態(tài)變量:0x%p ",&m2); printf("未初始化局部靜態(tài)變量 :0x%p ",&mp1); printf("已初始化局部靜態(tài)變量 :0x%p ",&mp2); printf(" 常量區(qū)地址 "); printf("已初始化只讀變量 :0x%p ",&m3); printf("已初始化局部指針變量 :0x%p ",vv ); printf("已初始化局部指針變量 :0x%p ",mq ); printf(" 代碼區(qū)地址 "); printf("程序代碼區(qū)main函數(shù)入口地址:0x%p ", main); led485_flicker(); delay_ms(1000); free(p1); free(p2); } }
-
存儲器
+關注
關注
38文章
7525瀏覽量
164151 -
cpu
+關注
關注
68文章
10898瀏覽量
212601 -
內存
+關注
關注
8文章
3045瀏覽量
74205 -
STM32
+關注
關注
2270文章
10921瀏覽量
356979 -
C語言
+關注
關注
180文章
7614瀏覽量
137383
原文標題:1. 詳細代碼如下
文章出處:【微信號:技術讓夢想更偉大,微信公眾號:技術讓夢想更偉大】歡迎添加關注!文章轉載請注明出處。
發(fā)布評論請先 登錄
相關推薦
評論