Skip to content

C++的内存管理

在 C++ 中,程序的内存分布主要分为以下几个区域:堆(Heap)、栈(Stack)、数据段(Data Segment),以及代码段(Code Segment)。每个区域有不同的用途和特性。

栈(Stack)

  1. 用途:栈用于存储局部变量和函数调用的相关信息(如函数参数、返回地址、局部变量等)。
  2. 管理方式:由编译器自动管理。
  3. 特点
  4. 栈内存分配方式是后进先出(LIFO, Last In First Out)。
  5. 内存分配和释放速度快。
  6. 栈空间通常较小,有限制。
  7. 栈上的变量在函数调用结束后会自动销毁。
  8. 例子cpp void function() { int localVar = 10; // 局部变量存储在栈上 }

堆(Heap)

  1. 用途:堆用于动态分配内存,即程序在运行时通过 newmalloc 等函数分配的内存。
  2. 管理方式:由程序员手动管理(分配和释放)。
  3. 特点
  4. 内存分配不连续,比较灵活。
  5. 内存空间较大,但需要手动管理(需要 deletefree 释放)。
  6. 内存分配和释放速度较慢。
  7. 适合用于需要在函数调用之间持久化的对象或数据结构。
  8. 例子cpp int* ptr = new int; // 动态分配内存,存储在堆上 *ptr = 5; delete ptr; // 释放堆内存

数据段(Data Segment)

数据段又细分为两个主要部分:全局/静态数据段(Global/Static Data Segment)和 BSS 段(Block Started by Symbol)。

  1. 用途:存储全局变量、静态变量和常量。
  2. 管理方式:由操作系统在程序启动时分配和初始化,在程序结束时释放。
  3. 特点
  4. 全局/静态数据段:用于存储已初始化的全局变量和静态变量。程序启动时分配并初始化这些变量,程序结束时释放。 cpp int globalVar = 10; // 已初始化的全局变量 static int staticVar = 20; // 已初始化的静态变量
  5. BSS 段:用于存储未初始化的全局变量和静态变量。程序启动时自动初始化为 0。 cpp int uninitializedGlobalVar; // 未初始化的全局变量 static int uninitializedStaticVar; // 未初始化的静态变量

代码段(Code Segment)

  1. 用途:存储程序的可执行代码。
  2. 管理方式:由操作系统在程序加载时分配和初始化。
  3. 特点
  4. 只读区域,防止程序意外修改指令。
  5. 包含程序的所有函数和方法的机器代码。

内存布局示意图

+-----------------------+
|       代码段         |  (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;
}