Logo成贤计协指南

堆与栈

浅谈堆与栈是什么

该节仅为基础介绍,如果想要了解更加深入的内容,建议自行查询

在学习 C/C++ 的过程中,经常会听到“堆”和“栈”这两个词。它们是程序运行时内存的两种不同区域,对于理解变量的生命周期、指针、动态内存分配等内容非常重要。本节将带你认识堆和栈的本质、区别以及它们在实际编程中的应用。

什么是栈(Stack)

是一种由系统自动管理的内存区域,主要用于存放局部变量函数参数返回地址等。你可以把栈想象成一个“自动收纳盒”,当你进入一个函数时,系统会自动为该函数分配一块栈空间,函数结束后,这块空间会自动释放。

栈的特点:

  • 自动分配和释放:进入函数时自动分配,离开函数时自动释放,无需程序员手动管理。
  • 存储局部变量和参数:如 int a = 10;void func(int x) 中的 x
  • 空间较小:栈的大小一般有限(几百 KB 到几 MB),如果分配太多会导致“栈溢出”。
  • 速度快:由于分配和释放由系统自动完成,速度非常快。

举个例子:

void func() {
    int a = 10; // a 是局部变量,存放在栈上
}

func() 被调用时,系统会在栈上分配空间给变量 a,当函数的生命周期结束后,a 所占用的空间会自动释放。

什么是堆(Heap)

是一种由程序员手动管理的内存区域,主要用于动态分配内存。你可以把堆想象成一个“自助仓库”,需要多少空间就自己去申请,用完了要自己归还。

堆的特点:

  • 手动分配和释放:需要程序员使用 new/delete(C++),或 malloc/free(C)来管理内存。
  • 存储动态分配的变量:如 int* p = new int(10);p 指向的内存就在堆上。
  • 空间较大:堆的空间一般比栈大得多,可以存放大量数据(如大数组、复杂对象)。
  • 速度较慢:分配和释放需要操作系统参与,速度比栈慢一些。

举个例子:

int* p = new int(10); // 在堆上分配一个 int,p 指向这块内存
delete p; // 用完后需要手动释放

为什么要用堆?

有些情况下,局部变量的生命周期太短,或者需要存储大量数据,栈空间不够用,这时就需要用堆来动态分配内存。例如:

  • 需要在函数外部访问或保存数据(如返回数组、对象等)
  • 需要存储大量数据(如大数组、链表、树等数据结构)
  • 需要灵活控制内存的分配和释放

举个例子,假如你想在函数中创建一个数组,并返回给外部使用:

注意

如果你忘记释放堆上的内存,就会造成内存泄漏,程序运行时间长了占用的内存会越来越多,导致严重的后果。。目前已经有很多方式来自动管理堆内存,比如说 C++ 的智能指针等等。因此,在现代 C++ 编程中,除非有特殊需求(如底层优化、与 C 接口交互等),否则不建议手动管理堆内存