堆与栈
浅谈堆与栈是什么
该节仅为基础介绍,如果想要了解更加深入的内容,建议自行查询
在学习 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 接口交互等),否则不建议手动管理堆内存。