从低地址到高地址
±------------------------+
| 代码段 | (Code Segment)
±------------------------+
| 已初始化数据段 | (Initialized Data Segment)
±------------------------+
| 常量区 | (Read-Only Data Segment)
±------------------------+
| 未初始化数据段 | (BSS Segment)
±------------------------+
| 堆区 | (Heap / Free Store)
| <从低地址向高地址增长> |
±------------------------+
| 栈区 | (Stack)
| <从高地址向低地址增长> |
±------------------------+
C++中的内存分区通常指的是程序运行时内存的分配方式。每个C++程序运行时,操作系统为其分配一定的内存空间,这些内存被划分为不同的区域,分别存放不同类型的数据。通常情况下,内存分为以下几个区域:
- 代码段(Code Segment)
- 存放内容:存放程序的可执行代码,所有的函数和方法代码都在这个区域。这个区域通常是只读的,以防止代码被意外或恶意修改。
- 特点:代码段的大小在编译时已经确定,运行时不会改变。
- 数据段(Data Segment)
- 存放内容:存储全局变量、静态变量和常量。这个区域又可以分为两个子区:已初始化数据段(Initialized Data Segment):存储已初始化的全局变量和静态变量。例如,
int x = 5;会被存放在这里。未初始化数据段(BSS,Block Started by Symbol):存储未初始化的全局变量和静态变量。这些变量在程序启动时会被自动初始化为零。例如,int x; 会被存放在这个区域。 - 特点:数据段在程序的生命周期中一直存在,直到程序结束为止。
- 常量区(Read-Only Data Segment)
- 存放内容:存储常量数据,例如字符串字面量和const修饰的全局变量。这个区域通常是只读的,如果尝试修改常量,会导致程序崩溃。
- 特点:常量区与数据段有时会合并,属于静态存储区的一部分,但与已初始化数据不同,它是只读的。
- 堆(Heap)
- 存放内容:用于动态分配的内存,程序在运行时通过new或malloc等操作从堆中分配内存。这块内存需要程序员手动管理,分配后必须通过delete或free来释放。自由存储区(Free Store)通常是通过new和delete管理的内存区域,与堆(Heap)密切相关。严格来说,自由存储区可以被看作是堆的一部分,因为它们的功能非常相似,都是用于动态内存分配的。不过,C++标准将通过new/delete管理的内存称为自由存储区,而堆更常与底层的malloc/free相关联。
- 特点:内存可以在程序运行期间动态增长和释放。
堆内存的分配和释放速度较慢,因为它涉及到复杂的内存管理机制,如空闲列表等。不释放内存可能会导致内存泄漏。
- 栈(Stack)
- 存放内容:用于函数调用过程中存储局部变量、函数参数和返回地址。每当调用一个函数时,都会在栈上为该函数创建一个新的栈帧,存储函数内部的局部变量和参数。函数返回时,相应的栈帧会被销毁。
- 特点:栈的分配和释放非常高效,因为它只是简单地移动栈指针。
栈的大小是有限的(通常只有几兆字节),如果递归调用过多或局部变量过大,可能会导致栈溢出。
栈内存是自动管理的,当一个函数执行结束后,栈帧会自动销毁,局部变量的内存会被释放。
**堆和栈的增长方向:**堆区从低地址向高地址增长,而栈区则相反,从高地址向低地址增长。这样做是为了让堆和栈能够各自扩展而不会冲突。
特点总结
代码段:存储程序的可执行指令,是只读的。
数据段:包括已初始化和未初始化的全局和静态变量,程序执行期间存在。
堆:用于动态分配的大块内存,手动管理分配和释放。
栈:用于函数调用时存储局部变量和参数,自动管理内存分配和释放。
常量区:存储程序中的常量数据,只读。
676

被折叠的 条评论
为什么被折叠?



