内存分区
从低地址到高地址分别是:
(1) 代码段(.text): 也称文本段,存放编译后的二进制文件和只读常量。 .text 段是只读的,大小在运行时是固定的。
(2) 数据段:
①已初始化的数据段(.data): 存放全局和静态的已初始化变量。.data段只读,大小在运行时是固定的。
②未初始化的数据段(.bss): 存放全局和静态的未初始化变量。.bss段应可读可写,大小运行时也是固定的。
(3)堆(heap): 用来存储程序运行时动态分配的变量。堆内存的分配释放一般由程序中的 new/delete,malloc/free等内存函数实现。如果程序没有释放该部分内存,则在程序结束后由系统回收。向上增长。
(4)栈stack):存放非静态局部变量/函数参数/返回值等信息,编译器自动分配和释放。向下增长。
(5)堆栈之间是内存映射段:进程间通信使用共享内存时会用到,加载动态库之后,动态库中函数的映射关系也存在这里。
(6)环境变量/命令行参数: 存储运行时可能用到的环境变量的副本、命令行参数。
(7)最上边是内核空间(图中没有),用户不可访问
C++动态内存管理方式
C++使用new和delete来动态申请和释放内存,这二者和malloc/free的区别不赘述。
operator new 和operator delete是系统提供的全局函数,new在底层调用operator new全局函数来申请空间,operator new里其实也是调用了malloc。delete在底层通过operator delete全局函数来释放空间,operator delete最终也是通过free来释放空间。
内存泄漏
内存泄漏是指程序未释放已经不再使用的内存,或者说为程序分配某段内存后,因为某种错误,失去了对该段内存的控制。
通常指堆内存泄漏,比如malloc或者new之后,没有执行对应的free或者delete。
还有系统资源泄漏,比如套接字、管道、文件描述符没有释放。
如何避免:
良好的编码习惯、使用智能指针、使用内存泄露检测工具。
智能指针
点击这里🔗
其他内存相关问题
堆和栈的不同
点击这里🔗