C / C++ 内存管理
C / C++内存分布
转载https://www.coonote.com/note/cpp-memory-management.html
C/C++程序内存分配的几个区域:
- 栈区(stack)
在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、返回地址等。 - 堆区(heap)
一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。分配方式类似于链表。 - 数据段(静态区)
(static)存放全局变量、静态数据。程序结束后由系统释放。 - 代码段
存放函数体(类成员函数和全局函数)的二进制代码
可以使用
使用size命令和objdump来查看目标文件的结构和内容:
bss段:
bss段(bss segment)通常是指用来存放程序中未初始化的全局变量
,未初始化的(全局以及局部)静态变量
的一块内存区域。
bss是英文Block Started by Symbol
的简称。
bss 段,不为数据分配空间,只是记录数据所需空间的大小;
bss 段的大小从可执行文件中得到 ,然后链接器得到这个大小的内存块,紧跟在data段后面
bss段属于静态内存分配。
data段:
数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。
用来存放有初始值的全局变量
、初始化的(全局以及局部)静态变量(static 关键字定义的变量)
。
text段:
代码段(code segment/text segment)
通常是指用来存放程序执行代码的一块内存区域。
这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读(某些架构也允许代码段为可写,即允许修改程序)。
在代码段中,也有可能包含一些只读的常数变量,例如字符串常量,常量(const 关键字定义的变量)等
- 通常text也可以分出一个
rodata
段 .rodata段 是 只读数据段,比如我们用const修饰的值就是放在这个区域的。
stack 栈区
用来存放局部变量
,函数的参数
,返回值
等,由编译器自动分配释放。如一个函数被调用后,产生的临时变量都会存到栈区的顶部,当函数完成后,会自动从顶部将刚使用的数据销毁。栈区的地址是从高地址向下增长的。
heap 堆区
用来动态内存分配,如 malloc
, new
申请的内存,由程序员手动分配释放。程序中不释放,则程序结束时,由OS回收;
从不同的角度去看
总结
未初始化的全局变量、静态局部变量,存储在.bss段中,具体体现为一个占位符;
已初始化的全局变量、静态局部变量,存储在.data段中;
此外,非静态局部变量,都在栈中分配空间。