(1)內存組成
(2)內存佈局
Linux所有應用程序都是從0x80480000開始,
其中0x80480000是一個虛擬地址
1)下面來測試一下應用程序的地址分佈
#include <stdio.h>int global_init_a=1; //全局的,初始化的變量 : 數據段
int global_uninit_a; //全局的,沒有初始化的變量 : 數據段
static int static_global_init_a = 1; //全局的,靜態的,初始化的變量 : 數據段
static int static_global_uninit_a; //全局的,靜態的,未初始化的變量 : 數據段
const int const_global_a = 1; //全局的,常量 : 代碼段
int global_init_b=1; //全局的,初始化的變量 : 數據段
int global_uninit_b; //全局的,沒有初始化的變量 : 數據段
static int static_global_init_b = 1; //全局的,靜態的,初始化的變量 : 數據段
static int static_global_uninit_b; //全局的,靜態的,未初始化的變量 : 數據段
const int const_global_b = 1; //全局的,常量 : 代碼段
int main(void)
{
int local_init_a=1;//局部的,初始化的變量 : 棧
int local_uninit_a;//局部的,沒有初始化的變量 : 棧
static int static_local_init_a = 1; //局部的,靜態的,初始化的變量 : 數據段
static int static_local_uninit_a; //局部的,靜態的,未初始化的變量 : 數據段
const int const_local_a = 1; //局部的,常量 : 棧
int local_init_b=1;//局部的,初始化的變量 : 棧
int local_uninit_b;//局部的,沒有初始化的變量 : 棧
static int static_local_init_b = 1; //局部的,靜態的,初始化的變量 : 數據段
static int static_local_uninit_b; //局部的,靜態的,未初始化的變量 : 數據段
const int const_local_b = 1; //局部的,常量 : 棧
int * malloc_p_a;//局部的,指針
malloc_p_a=malloc(sizeof(int)); //通過malloc分配得到的,局部 : 堆
printf(“&global_init_a=%p, global_init_a=%d\n”,&global_init_a,global_init_a);
printf(“&global_uninit_a=%p, global_uninit_a=%d\n”,&global_uninit_a,global_uninit_a);
printf(“&static_global_init_a=%p, static_global_init_a=%d\n”,&static_global_init_a,static_global_init_a);
printf(“&static_global_uninit_a=%p, static_global_uninit_a=%d\n”,&static_global_uninit_a,static_global_uninit_a);
printf(“&const_global_a=%p, const_global_a=%d\n”,&const_global_a,const_global_a);
printf(“&global_init_b=%p, global_init_b=%d\n”,&global_init_b,global_init_b);
printf(“&global_uninit_b=%p, global_uninit_b=%d\n”,&global_uninit_b,global_uninit_b);
printf(“&static_global_init_b=%p, static_global_init_b=%d\n”,&static_global_init_b,static_global_init_b);
printf(“&static_global_uninit_b=%p, static_global_uninit_b=%d\n”,&static_global_uninit_b,static_global_uninit_b);
printf(“&const_global_b=%p, const_global_b=%d\n”,&const_global_b,const_global_b);
printf(“&local_init_a=%p, local_init_a=%d\n”,&local_init_a,local_init_a);
printf(“&local_uninit_a=%p, local_uninit_a=%d\n”,&local_uninit_a,local_uninit_a);
printf(“&static_local_init_a=%p, static_local_init_a=%d\n”,&static_local_init_a,static_local_init_a);
printf(“&static_local_uninit_a=%p, static_local_uninit_a=%d\n”,&static_local_uninit_a,static_local_uninit_a);
printf(“&const_local_a=%p, const_local_a=%d\n”,&const_local_a,const_local_a);
printf(“&local_init_b=%p, local_init_b=%d\n”,&local_init_b,local_init_b);
printf(“&local_uninit_b=%p, local_uninit_b=%d\n”,&local_uninit_b,local_uninit_b);
printf(“&static_local_init_b=%p, static_local_init_b=%d\n”,&static_local_init_b,static_local_init_b);
printf(“&static_local_uninit_b=%p, static_local_uninit_b=%d\n”,&static_local_uninit_b,static_local_uninit_b);
printf(“&const_local_b=%p, const_local_b=%d\n”,&const_local_b,const_local_b);
printf(“malloc_p_a=%p, malloc_p_a=%d\n”,malloc_p_a,*malloc_p_a);
while(1)
;
return 0;
}
2) 編譯並運行程序,這裏不過多介紹
3) 另開起一個終端
ps -axu 查看系統所有進程,找到我們剛纔運行的程序./addr
cat /proc/進程PID/maps 查看內存分佈情況
結果如下:
兩張圖的地址段對比就可以知道程序中的變量在內存中如何存放的!
已經將對比的結果寫到程序的註釋中了.
4)BSS段去哪裏了?
1>首先查看程序的格式 file addr
由此可知應用程序addr是elf屬性的文件
2> 使用readelf -S addr 來查看bss的地址段
由此可知BSS(未初始化的數據段):
全局未初始化的變量(靜態的,非靜態的)
局部未初始化的變量(靜態的)
另一種方法:(就是麻煩點)
先判斷出所有變量的分佈,再找出未初始化的數據段的變量,即屬於BSS段
5) 總結:
5. BSS段:
全局未初始化的變量(靜態的,非靜態的)
局部未初始化的變量(靜態的)