动态内存分配(堆内存分配)
动态操作一般指程序运行期间做的操作。
/*
c方式
*/
#include <cstdlib>
int main() {
int* pm = malloc(4); // 分配4字节大小的内存,但是c++编译器会报错,因为malloc返回的类型是void*。在c编译器可以通过。
// int* pm = (int*) malloc(4); 可以做类型强转
free(pm); // 释放
return 0;
}
/*
c++方式
*/
#include <iostream>
using namespace std;
int main() {
int* pm = new int; // 分配内存
// int* pm = new int(10); // 分配内存并初始化值为10
// int* pm = new int[4]; // 分配数组内存,返回值为数组首元素的地址
// int* pm = new int[4]{1,2,3,4} // 分配数组内存并初始化,c++11标准才开始支持此方式
// delete []pm // 释放内存也需要用数组的方式释放
delete pm; // 释放
return 0;
}
分配数组内存说明
-
new int[10]的方式,执行逻辑是内存分配器可能会在分配的内存块之前或之后存储一些额外的信息,用于管理内存(如分配大小、内存对齐等),但这些信息不会被直接暴露给用户,如果直接delete 释放内存,则会导致多分配内存无法被释放,导致内存泄漏。所以需要用delete[] 的方式。
-
不管几维数组,应该当做一维数组进行分析
int(*p)[4] = new int [3] [4];
首地址类型应该为 int(*)[4]
释放多维数组,仍然用delete [] 的方式释放。
delete操作注意事项
不能delete已经delete的内存空间,因为第一次释放后,表示指向的内存被释放,原有的指针变为悬空指针(野指针的一种),再次释放可能会导致该指针指向的其他内存空间被释放,会导致不可预料后果。但是释放空指针是安全的,所有每次释放内存空间后,应该把该指针指向空指针(nullptr)。
new分配异常
如果new分配内存失败,则会抛出异常。
#include <iostream>
using namespace std;
int main() {
int* pm = new int[0xFFFFFFFFFFFFFFF]; // 分配过大
return 0;
}
异常处理
#include <iostream>
using namespace std;
int main() {
try{
int* pm = new int[0xFFFFFFFFFFFFFFF];
} catch(...) {
}
return 0;
}