目录
一、内存分区介绍
(一)C语言经编译后的分区情况
一个由C/C++编译的程序占用的内存分为以下几个部分 :
- 栈区(stack):由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
- 堆区(heap):一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。
- 全局区(静态区)(static):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量、未初始化的静态变量在相邻的另一块区域。程序结束后由系统释放 。
- 文字常量区 :常量字符串就是放在这里的。程序结束后由系统释放 。
- 程序代码区:存放函数体的二进制代码。
一个正常的程序在内存中通常分为程序段、数据端、堆栈三部分。程序段里放着程序的机器码、只读数据,这个段通常是只读,对它的写操作是非法的。数据段放的是程序中的静态数据。动态数据则通过堆栈来存放。
- C/C++不提供垃圾回收机制,因此需要对堆中的数据进行及时销毁,防止内存泄漏,使用free和delete销毁new和malloc申请的堆内存,而栈内存是动态释放。
全局变量、静态局部变量保存在全局数据区,初始化的和未初始化的分别保存在一起;
普通局部变量保存在堆栈中。
(二)动&静分配内存
- 静态分配内存:是在程序编译和链接时就确定好的内存。
-
动态分配内存:是在程序加载、调入、执行的时候分配/回收的内存。
(三)Text & Data & Bss
- .text: 也称为代码段(Code),用来存放程序执行代码,同时也可能会包含一些常量(如一些字符串常量等)。该段内存为静态分配,只读(某些架构可能允许修改)。
这块内存是共享的,当有多个相同进程(Process)存在时,共用同一个text段。 -
.data: 也有的地方叫GVAR(global value),用来存放程序中已经初始化的非零全局变量。静态分配。
data又可分为读写(RW)区域和只读(RO)区域。
-> RO段保存常量所以也被称为.constdata
-> RW段则是普通非常全局变量,静态变量就在其中 - .bss: 存放程序中为初始化的和零值全局变量。静态分配,在程序开始时通常会被清零。
text和data段都在可执行文件中,由系统从可执行文件中加载,而bss段不在可执行文件中,由系统初始化。 这三段内存就组成了我们编写的程序的本体。
(四)堆栈(Heap& Stack)
堆和栈都是动态分配内存,两者空间大小都是可变的。
-
Stack: 栈,存放Automatic Variables,按内存地址由高到低方向生长,其最大大小由编译时确定,速度快,但自由性差,最大空间不大。
-
Heap: 堆,自由申请的空间,按内存地址由低到高方向生长,其大小由系统内存/虚拟内存上限决定,速度较慢,但自由性大,可用空间大。
每个线程都会有自己的栈,但是堆空间是共用的。