机制
- 栈内存:由编译器自动分配和释放,遵循后进先出(LIFO)原则。函数调用时,其局部变量会在栈上分配空间,函数结束时,这些变量占用的栈空间自动被释放。
- 堆内存:由程序员手动分配和释放,通过
new
(C++)或malloc
(C语言)等操作从堆中申请内存,使用delete
(C++)或free
(C语言)释放。
生命周期
- 栈内存:局部变量的生命周期与函数调用紧密相关,函数执行结束,栈上变量占用空间自动释放。
- 堆内存:生命周期由程序员控制,一旦分配,直到程序员调用
delete
(或free
)释放,否则一直存在。若未及时释放,会造成内存泄漏。
内存管理方式
- 栈内存:编译器自动管理,无需程序员手动干预,简单高效,但栈空间大小有限。
- 堆内存:程序员手动管理,灵活性高,但易出错,如忘记释放导致内存泄漏,多次释放导致未定义行为。
适用场景
- 栈内存:适用于生命周期短、占用空间小且明确的变量,如函数内部的临时变量、小型结构体或对象。例如函数内的循环计数器
int i;
,在栈上分配,函数结束自动释放。
- 堆内存:适用于生命周期不确定、占用空间较大或需要动态分配大小的对象。如在运行时根据用户输入决定大小的数组,或需要在不同函数间共享的数据结构。
举例
void stackExample() {
int num = 10; // 栈上分配一个整数
std::string str = "Hello"; // 栈上分配一个字符串对象
// 函数结束,num和str占用的栈空间自动释放
}
void heapExample() {
int* ptr = new int(20); // 堆上分配一个整数
std::string* strPtr = new std::string("World"); // 堆上分配一个字符串对象
// 使用完后需手动释放
delete ptr;
delete strPtr;
}