這裏以 Linux 爲例,用 C 語言進行演示。html
- | 內存空間名稱 | 內容 | 讀寫操做 | 分配時機 |
---|---|---|---|---|
高地址 | kernel 內核空間 | 命令行參數、環境變量等 | 不可讀寫 | 程序運行時 |
- | stack 棧空間 | 局部變量 | 可讀寫 | 程序運行時 |
- | heap 堆空間 | malloc() new() 內存分配函數建立 | 可讀寫 | 程序運行時 |
- | 全局數據空間(初始化的和未初始化的) | 靜態變量、全局變量 | 可讀寫 | 編譯時 |
- | 只讀數據空間 | 程序的只讀數據(常量) | 只讀 | 編譯時 |
低地址 | 代碼段 | 程序的機器碼,相同程序的多個運行實體之間共享 | 只讀 | 編譯時 |
能夠經過 size 命令查看可執行文件的內存分配,其中 text 的大小對應程序的只讀空間(代碼段和只讀數據段),data 對應初始化了的全局數據、靜態變量,bss 是未初始化數據段,包含未經初始化的全局變量和靜態變量。詳細例子能夠參考:https://blog.csdn.net/love_gaohz/article/details/50522447,簡單示例以下:linux
#include <stdio.h> int b; int main() { int a = 888; }
上面代碼中有未初始化的全局變量,編譯後用 size 查看:web
[root@VM_139_38_centos 20190121]# size build text data bss dec hex filename 1127 540 12 1679 68f build
修改 C 代碼,初始化全局變量:centos
#include <stdio.h> int b = 666; int main() { int a = 888; }
初始化全局變量後,編譯後用 size 查看:bash
[root@VM_139_38_centos 20190121]# size build text data bss dec hex filename 1127 544 8 1679 68f build
# nm build
000000000060102c D b
0000000000601030 B __bss_start
0000000000601030 b completed.6355
0000000000601028 D __data_start
0000000000601028 W data_start
0000000000400430 t deregister_tm_clones
00000000004004a0 t __do_global_dtors_aux
0000000000600e18 t __do_global_dtors_aux_fini_array_entry
0000000000400588 R __dso_handle
0000000000600e28 d _DYNAMIC
0000000000601030 D _edata
0000000000601038 B _end
0000000000400574 T _fini
00000000004004c0 t frame_dummy
0000000000600e10 t __frame_dummy_init_array_entry
00000000004006b8 r __FRAME_END__
0000000000601000 d _GLOBAL_OFFSET_TABLE_
w __gmon_start__
00000000004003a8 T _init
0000000000600e18 t __init_array_end
0000000000600e10 t __init_array_start
0000000000400580 R _IO_stdin_used
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
0000000000600e20 d __JCR_END__
0000000000600e20 d __JCR_LIST__
w _Jv_RegisterClasses
0000000000400570 T __libc_csu_fini
0000000000400500 T __libc_csu_init
U __libc_start_main@@GLIBC_2.2.5
00000000004004ed T main
0000000000400460 t register_tm_clones
0000000000400400 T _start
0000000000601030 D __TMC_END__
[root@VM_139_38_centos 20190121]# strings build /lib64/ld-linux-x86-64.so.2 Z%1X libc.so.6 printf __libc_start_main __gmon_start__ GLIBC_2.2.5 UH-8 UH-8 []A\A]A^A_ address: const is:%p global is %p local is %p function main is %p ;*3$" ...
下面的例子演示了各類類型變量常量的內存地址的位置:svg
#include <stdio.h> const int a = 666; int b = 777; char * str = "hello\n"; int main() { int c = 888; printf("address: \nconst is:%p\n global is %p\n local is %p\n function main is %p\n string str is %p", &a, &b, &c, main, &str); unsigned char * p = main; //p[0] = 0x0; // 這裏訪問只讀的代碼段會報錯 str[3] = 'z'; // 這裏訪問只讀的代碼段會報錯 }
輸出爲:函數
address: const is:0x400600 global is 0x601034 local is 0x7ffdb921023c function main is 0x40052d string str is 0x601040
只讀空間在程序運行以前就分配好了,運行結束後纔回收。ui
#include <stdio.h> #include <stdlib.h> int main() { char *p = (char *)malloc(100); if (p == NULL) exit(1); int *a; a = (int *)malloc(sizeof(int)); if (a == NULL) { free(p); exit(1); } free(a); printf("end"); }