前言
在进行开发和学习的过程中,我们老是看到或听到“堆空间”,“栈区”,那么他们到底都是什么?有什么关联和区别呢?接下来我们一起看看。
什么是堆空间
堆空间是内存管理中的一种区域,用于动态地分配内存给程序中的对象。堆空间允许程序在运行时根据需要分配和释放内存
什么是栈区
栈区是内存中的一个区域,用于存储局部变量和函数调用的上下文信息。栈是一种后进先出的数据结构,它允许程序在调用函数时自动地分配和释放内存。
堆空间和栈区的区别
也就是说堆空间是程序员自己控制的,栈区是编译器控制的。
void demo()
{
int a=5;
double=1.9;
{
char c='A';
}//------c被释放
}//------a,b被释放
//栈空间完全跟随代码块不可手控控制
既然堆空间是我们程序员控制的,那它要怎么控制呢
方式一:通过库函数
#include <cstdlib>//堆操作库函数所需头文件
void Demo(){
void *buf = std::malloc(16);//申请16bytes堆空间
if(buf != nullptr){如果堆空间不足会返回空指针
// 按需使用
std::free(buf);-用完记得释放
方式二:使用malloc
和free
#include <stdio.h>
#include <stdlib.h>
int main() {
// 分配堆空间来存储一个int类型的值
int *ptr = (int*)malloc(sizeof(int));
if (ptr == NULL) {
// 内存分配失败
printf("Memory allocation failed\n");
return 1;
}
// 使用分配的内存
*ptr = 10;
printf("Value = %d\n", *ptr);
// 释放内存
free(ptr);
return 0;
}
方式三:中使用new
和delete
#include <iostream>
int main() {
// 分配堆空间来存储一个int类型的值
int* ptr = new int;
// 使用分配的内存
*ptr = 20;
std::cout << "Value = " << *ptr << std::endl;
// 释放内存
delete ptr;
return 0;
}
方式四:使用new[]
和delete[]
(对于数组)
#include <iostream>
int main() {
// 分配堆空间来存储一个int类型的数组,大小为5
int* arr = new int[5];
// 初始化数组
for (int i = 0; i < 5; ++i) {
arr[i] = i * 2;
}
// 使用数组
for (int i = 0; i < 5; ++i) {
std::cout << arr[i] << " ";
}
std::cout << std::endl;
// 释放内存
delete[] arr;
return 0;
}
注意
- 使用
malloc
和free
时,需要手动进行类型转换(如(int*)
),而在C++中,使用new
和delete
时,不需要这样做,因为new
操作符已经返回了正确的指针类型。 - 当使用
new[]
分配数组时,必须使用delete[]
来释放内存,而不是delete
。这是因为delete[]
会调用数组中每个对象的析构函数(如果有的话),而delete
则只调用一个对象的析构函数。 - 忘记释放分配的内存会导致内存泄漏,因此务必在不再需要堆内存时释放它。
- 在C++中,除了直接使用
new
和delete
之外,还可以使用智能指针(如std::unique_ptr
、std::shared_ptr
)来自动管理堆内存,从而减少内存泄漏的风险。