环境
ubuntu 16.04 64 g++ 6.3
实例文件 tes.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 using namespace std;int global_a; int global_b = 0 ; int global_c = 3 ; static int static_global_a; static int static_global_b = 3 ; const int const_global_a = 0 ; const int const_global_b = 1 ; const static int const_static_global_a = 0 ; const static int const_static_global_b = 1 ; int main () { static int local_static_a; static int local_static_b = 3 ; const static int local_const_static_a = 0 ; const static int local_const_static_b = 1 ; const int local_const_a = 0 ; const int local_const_b = 1 ; int local_a; return 0 ; }
相关命令 1 2 3 4 5 g++-6 -c tes.cpp -o tes.o size tes.o objdump -CS -s -j .data tes.o readelf -all tes.o nm ./a.out
步骤 编译单个tes.cpp文件 1 2 g++-6 -c tes.cpp -o tes.o g++-6 tes.cpp
查看大小 1 2 3 X@DESKTOP-LMTTY:~/test$ size tes.o text data bss dec hex filename 105 12 16 129 81 tes.o
反编译查看各分区 .data
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 X@DESKTOP-LMTTY:~/test$ objdump -CS -s -j .data tes.o tes.o: file format elf64-x86-64 Contents of section .data: 0000 03000000 03000000 03000000 ............ Disassembly of section .data: 0000000000000000 <global_c>: 0: 03 00 00 00 .... 0000000000000004 <static_global_b>: 4: 03 00 00 00 .... 0000000000000008 <main::local_static_b>: 8: 03 00 00 00 ....
.bss
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 X@DESKTOP-LMTTY:~/test$ objdump -CS -s -j .bss tes.o tes.o: file format elf64-x86-64 Disassembly of section .bss: 0000000000000000 <global_a>: 0: 00 00 00 00 .... 0000000000000004 <global_b>: 4: 00 00 00 00 .... 0000000000000008 <static_global_a>: 8: 00 00 00 00 .... 000000000000000c <main::local_static_a>: c: 00 00 00 00 ....
.rodata
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 X@DESKTOP-LMTTY:~/test$ objdump -CS -s -j .rodata tes.o tes.o: file format elf64-x86-64 Contents of section .rodata: 0000 00000000 01000000 00000000 01000000 ................ 0010 00000000 01000000 ........ Disassembly of section .rodata: 0000000000000000 <const_global_a>: 0: 00 00 00 00 .... 0000000000000004 <const_global_b>: 4: 01 00 00 00 .... 0000000000000008 <const_static_global_a>: 8: 00 00 00 00 .... 000000000000000c <const_static_global_b>: c: 01 00 00 00 .... 0000000000000010 <main::local_const_static_a>: 10: 00 00 00 00 .... 0000000000000014 <main::local_const_static_b>: 14: 01 00 00 00 ....
查看符号表 1 2 3 4 5 6 7 8 9 10 11 12 13 14 X@DESKTOP-LMTTY:~/test$ nm tes.o 0000000000000000 B global_a 0000000000000004 B global_b 0000000000000000 D global_c 0000000000000000 T main 0000000000000000 r _ZL14const_global_a 0000000000000004 r _ZL14const_global_b 0000000000000008 b _ZL15static_global_a 0000000000000008 r _ZL21const_static_global_a 000000000000000c r _ZL21const_static_global_b 000000000000000c b _ZZ4mainE14local_static_a 0000000000000004 d _ZZ4mainE14local_static_b 0000000000000010 r _ZZ4mainE20local_const_static_a 0000000000000014 r _ZZ4mainE20local_const_static_b
nm解释参考http://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/nm.html
总结 C++中内存从低地址到高地址分别为:
.text segment: 代码段
.rodata segment: 存储常量,例如字符串常量,const修饰的变量。
.data segment: 又称GVAR.存储已经初始化的非零全局变量和静态变量(全局/局部)
.bss segment: BSS segment也称为未初始化的数据段,包含全局或静态未初始化的变量,该部分数据中的值会在程序启动时直接初始为0,BSS是Block Started by Symbol的简写
heap: 堆,动态内存区域,使用malloc或new申请的内存.向地址变大的方向增长.
自由存储区: 未使用的内存
stack: 栈,局部变量、参数、返回值都存在这里,函数调用开始会参数入栈、局部变量入栈;调用结束依次出栈。向地址变小的方向增长.
参考 实例分析C++内存布局 C/C++中已初始化/未初始化全局/静态/局部变量/常量在内存中的位置 https://en.wikipedia.org/wiki/Data_segment