malloc/free是C中的函数,用于在堆区开辟释放空间。
用法:
//malloc/free用法
int *p = (int*)malloc(sizeof(int));
if (p) {
*p = 5;
cout << *p << endl;
free(p);
}
特点:1.需要显式指定开辟空间的字节长度;
2.malloc返回值为void *,需要类型转换。
new/delete是C++中的操作符/关键字
三种用法:
//new第一种用法
//指针变量名 = new 类型标识符
int *myint = new int;
if (myint) {
*myint = 8;
cout << *myint << endl;
delete myint;
}
//new第二种用法
//指针变量名 = new 类型标识符(初始值)
int *myint = new int(19);
if (myint) {
cout << *myint << endl;
delete myint;
}
//new第三种用法
//指针变量名 = new 类型标识符[数组长度] 为数组开辟内存
int *ptr = new int[100];
if (ptr) {
int *p = ptr;
*p++ = 1;
*p++ = 2;
cout << *ptr << endl;
cout << *(ptr + 1) << endl;
delete[] ptr;//释放数组内存要用delete[]
}
特点:1.会根据类型自动推导需要开辟的内存长度;
2.返回类型为具体的类型指针。
3.相比于malloc/free会调用构造和析构函数;
4.有专门用于开辟释放数组的版本new[],delete[]。
补充(2021/10/9):
new内部有记录机制存放开辟内存的大小,这种记录几种因编译器而异,delete在释放内存时会读取该内存大小进行释放,做到开辟多少释放多少。
在使用new之后,会先调用operator new()函数开辟内存,再调用析构函数(如果有的话);
再使用delete之后,会先调用析构函数(如果有的话),再调用operator delete()函数释放内存。
对于new[]\delete[]的补充:
1.如果使用new[]为一个包含自定义析构函数的类开辟数组,那么new[]会在原有数组字节长度的基础上额外开辟4字节用于存放数组长度(元素个数),在使用delete[]释放内存时会读取数组长度,并按数组长度多次调用析构函数。如果为内置类型或无自定义析构函数的类开辟内存,则不会额外开辟4字节,因为delete[]无需调用析构函数。
2.在使用new[]为数组开辟内存后,若数据类型为内置类型或无自定义析构函数的类,则使用delete或delete[]都可以正常释放内存,但不推荐使用delete释放。若类型为包含自定义析构函数的类,则必须用delete[]释放内存。如果使用delete释放内存,则会因为额外开辟的4字节空间导致释放的内存空间错乱(具体机理有待探究),引起错误。
3.如果使用new为一个包含自定义析构函数的类开辟内存,但使用delete[]释放空间,会产生未知错误。因为在使用new时并没有开辟额外4字节空间,但使用delete[]时会去读取4字节的内容,这就导致读取上来的数据未知,产生不可预见的结果。
综上:new\delete、new[]\delete[]要配对使用。
水平有限,边学习边总结。