文章目录
前置回顾: 简单了解new & delete
在C语言中, 动态内存的申请使用的是malloc和calloc, 而C++中提供了更加智能的方案:new
new的内存申请:
ew会自动判断所需内存大小, 并返回合适的指针
typeName * ptrName = new typeName ; //自动判断typeName类型的大小
//如:
int *ptr1=new int; //申请一块int大小的内存, 默认初始化
int *ptr2=new int(5); //申请一块int大小的内存, 使用内置类型构造函数将值初始化为5
int *ptr3=new int[5]; //申请5块int大小的内存(通常作为数组使用), 默认初始化
new申请内存失败的情况:
当New申请内存失败时, 通常会有两种情况:
- 抛出bad_alloc异常来报告分配失败
- 返回NULL,而不会抛出异常
由于部分编译器对C++标准的支持问题, 有些编译器会返回NULL(如VC++6.0), 而对标准支持较好的编译器会返回异常(如GCC)
内存申请失败的原因:
- 系统内存不足
此问题较为明显, 当内存不足时肯定会失败, 这没啥好说的 - token handle过多不释放
此时如果内存量充足仍然会导致new
delete的内存释放:
int *ptr=new int;
int *ptrCopy=ptr;
//二者等价, 取其一
delete ptr;
delete ptrCopy;
delete的使用与free相似:
- 不可以两次的释放同一块内存, 这是未定义操作
- 使用时可以传入空指针, delete和free都会针对空指针进行优化, 不会出现问题(连警告都没有)
原则上不能使用delete释放malloc申请的内存, 同样, 也不要用free释放new申请的内存, 将两者混用, 会出现意想不到的问题. 如内存未完全释放, 释放失败等
注意这里编译器不给出任何警告, 使用时要注意, 不要挖坑给自己跳
实际上delete的操作数应该是new的返回值, 即返回申请的内存开头的地址, 而非指针
针对数组的delete:
int *ptrArr= new int[100];
delete [] ptrArr;
释放数组的内存必须使用delete[], 且操作数必须为数组首元素地址
如果使用delete, 或是使用数组其他元素的地址, 将是undefined behavior (UB) 未定义行为
关于内存空间是否真的被释放:
这个问题和内存释放的定义有关,
关于其他功能
对于new一块内存, 而后部分释放的功能, 系统并未提供, 需要开发者手动封装(如内存池)