C++的内存管理
在 C++ 中,程序的内存分布主要分为以下几个区域:堆(Heap)、栈(Stack)、数据段(Data Segment),以及代码段(Code Segment)。每个区域有不同的用途和特性。
栈(Stack)
- 用途:栈用于存储局部变量和函数调用的相关信息(如函数参数、返回地址、局部变量等)。
- 管理方式:由编译器自动管理。
- 特点:
- 栈内存分配方式是后进先出(LIFO, Last In First Out)。
- 内存分配和释放速度快。
- 栈空间通常较小,有限制。
- 栈上的变量在函数调用结束后会自动销毁。
- 例子:
cpp void function() { int localVar = 10; // 局部变量存储在栈上 }
堆(Heap)
- 用途:堆用于动态分配内存,即程序在运行时通过
new
或malloc
等函数分配的内存。 - 管理方式:由程序员手动管理(分配和释放)。
- 特点:
- 内存分配不连续,比较灵活。
- 内存空间较大,但需要手动管理(需要
delete
或free
释放)。 - 内存分配和释放速度较慢。
- 适合用于需要在函数调用之间持久化的对象或数据结构。
- 例子:
cpp int* ptr = new int; // 动态分配内存,存储在堆上 *ptr = 5; delete ptr; // 释放堆内存
数据段(Data Segment)
数据段又细分为两个主要部分:全局/静态数据段(Global/Static Data Segment)和 BSS 段(Block Started by Symbol)。
- 用途:存储全局变量、静态变量和常量。
- 管理方式:由操作系统在程序启动时分配和初始化,在程序结束时释放。
- 特点:
- 全局/静态数据段:用于存储已初始化的全局变量和静态变量。程序启动时分配并初始化这些变量,程序结束时释放。
cpp int globalVar = 10; // 已初始化的全局变量 static int staticVar = 20; // 已初始化的静态变量
- BSS 段:用于存储未初始化的全局变量和静态变量。程序启动时自动初始化为 0。
cpp int uninitializedGlobalVar; // 未初始化的全局变量 static int uninitializedStaticVar; // 未初始化的静态变量
代码段(Code Segment)
- 用途:存储程序的可执行代码。
- 管理方式:由操作系统在程序加载时分配和初始化。
- 特点:
- 只读区域,防止程序意外修改指令。
- 包含程序的所有函数和方法的机器代码。
内存布局示意图
+-----------------------+
| 代码段 | (Code Segment)
| (程序的指令) |
+-----------------------+
| 数据段 | (Data Segment)全局/静态数据段(Global/Static Data Segment)和 BSS 段(Block Started by Symbol)
| (已初始化和未初始化) |
+-----------------------+
| 堆 | (Heap)
| (动态分配的内存) |
+-----------------------+
| 栈 | (Stack)
| (函数调用和局部变量) |
+-----------------------+
参考示例
#include <iostream>
using namespace std;
// 全局变量 - 数据段
int globalVar = 10;
// 未初始化的全局变量 - BSS 段
int uninitializedGlobalVar;
void function() {
// 局部变量 - 栈
int localVar = 5;
// 动态分配内存 - 堆
int* heapVar = new int(20);
cout << "局部变量: " << localVar << endl;
cout << "动态分配内存: " << *heapVar << endl;
// 释放堆内存
delete heapVar;
}
int main() {
function();
cout << "全局变量: " << globalVar << endl;
cout << "未初始化的全局变量: " << uninitializedGlobalVar << endl;
return 0;
}