1. 程式人生 > >C程序運行時的內存分布

C程序運行時的內存分布

style 不為 程序 res pri 完成 har 17. 原因

該片博客是自己學習的總結,如果有哪裏理解的不對的地方,希望大家可以指點。

一、C內存空間分布圖

技術分享圖片

二、各內存區域詳解

1.代碼區(.text): 該區域主要存放二進制可執行文件。

2.數據區(.data): 數據區可詳細分為三塊區域,分別是只讀數據區、初始化數據區、未初始化數據區。

1). 只讀數據區(.ordata) : 顧名思義,這個區域存放的是一些常量,包括字符串常量、const修飾的全局變量;

註意一: 字符串常量都是存儲在只讀數據區的。看下面一個例子,

 1 #include <stdio.h>
 2
3 int main(void) 4 { 5 char str[] = "I Love CHINA"; 6 7 printf("the address of array: %p\n", str); 8 printg("the address of string: %p\n", "I Love CHINA"); 9 10 str[0] = W; 11 printf("%s\n", str); 12 13 return 0; 14 }

調試結構為:

the address of array: 0xbfa5052f

the address of string: 0x80485f5
W Love CHINA

看到這裏可能就迷糊了,上面不是說字符串常量都存放在只讀數據區嗎?其實原因是這樣的,當我們用字符串初始化字符數組時,是先將字符串字面量存儲在只讀數據區,當調用該初始化所在函數時,會將在數據區的數據拷貝一份到當前數組,當前運行的程序中就有兩個‘‘I Love CHINA‘‘;我們改變了的其實是賦值到字符數組str所對應的在棧中的空間的值,而存放在數據區的字符串常量並沒有改變。

註意二: 而const修飾的局部變量還是像普通的局部變量一樣存放在棧中,只是不能顯式的改變該變量。

2). 初始化數據區(.rwdata): 該區域用來存放初始化不為0

的全局變量和static修飾的局部變量。

3). 未初始化數據區(.bss): 與初始化數據區類似,但是它存放的是初始化為0、未初始化的全局變量和static修飾的局部變量。這樣做的目的主要是為了減少可執行二進制文件占用的存儲空間,特別是在一些嵌入式設備中顯得尤其重要。如下圖,

 1 #include <stdio.h>
 2 
 3 int arr[2000] = {2};
 4 
 5 int main(void)
 6 {
 7     printf("hello world\n");
 8 
 9     return 0;
10 }

技術分享圖片

 1 #include <stdio.h>
 2 
 3 int arr[2000] = {0};
 4  
 5 int main(void)
 6 {
 7      printf("hello world\n");
 8  
 9      return 0;
10 }

技術分享圖片

3. 棧: 棧存放的是程序中的局部變量, 當然函數形參、返回值也都存儲在棧中。棧是由系統自動管理,變量的出棧入棧操作都由系統通過移動棧頂指針來完成來完成,並不是真正的清除變量,所以當我們使用局部變量之前一定要給它賦值,否則就是一個不確定的值。

4.堆: 堆空間解決了自動分配不靈活,對內存造成浪費等問題。可以通過malloc函數申請所需大小的空間,註意這塊空間申請了之後會一直存在,所以一定要和free一起使用,等用完之後馬上釋放,否則會造成內存泄漏,嚴重會導致程序停止運行。我們使用mallco函數帶來方便靈活的同時,也帶來了內存碎片的問題,所以當要求程序長時間運行時,必不可免的就要解決malloc帶來的內存碎片問題。

C程序運行時的內存分布