new
和delete
是操作符,malloc
和free
是库函数。
执行new
实际上执行了两个操作:1、分配未初始化的内存空间,也就是调用malloc
库函数。2、使用对象的构造函数对空间进行初始化,并返回空间的首地址。
如果第一步分配空间出现问题,则会直接抛出std::bad_alloc
异常,或被某个设定的异常处理函数处理。如果第二步构造对象是出现异常,则调用delete
释放内存。
执行delete
实际上也是有两个过程:1、使用析构函数对对象进行析构。2、回收内存空间,也就是调用free
库函数。
new
和malloc
的区别:new
得到的是经过初始化的空间,而malloc
得到的是未初始化的空间。所以new
是new
一个类型,而malloc
则是malloc
一个字节长度的空间。new
通过std::bad_alloc
异常来判断是否空间分配成功,而malloc
使用返回值和nullptr
比较来判断空间是否分配成功。malloc
创建空间本身是无类型的。
delete
和free
的区别:delete
不仅会释放空间,还析构对象。delete
一个类型,free
一个字节长度的空间。
为什么在已经有malloc/free
还需要new/delete
?因为对于非内部数据类型而言(自定义对象等),光用malloc/free
无法满足动态对象的要求。对象在创建的同时需要自动执行构造函数,对象在消亡的之前自动执行析构函数。由于malloc/free
是库函数而不是运算符,不在编译器控制权限之内,不能把执行构造函数和析构函数的任务强加于malloc/free
,所以就有了new/delete
操作符。
new初始化变量和常量指针
#include <iostream>
#include <string>
using namespace std;
int main()
{
// 4种new初始化
int *p1 = new int(20); // 最正常的
int *p2 = new (nothrow) int(20); // 不会抛出异常的
const int *p3 = new const int(20); // 常量指针类型
int a = 0;
int *p4 = new (&a) int(50); // 定位new,将原来变量a的地址中的值改为当前初始化的值,p4的地址和a的地址一致
// 0x632410 0x632450 0x632490 0x61fdfc 50 0x61fdfc
cout << p1 << " " << p2 << " " << p3 << " " << p4 << " " << a << " " << &a << endl;
return 0;
}
new/malloc和delete/free常规使用区别
#include <iostream>
#include <string>
using namespace std;
int main()
{
int *p1 = (int*)malloc(sizeof(int)); // malloc创建空间,并强制转化给它一个类型
if(p1==nullptr) // 判断空间是否分配成功
{
return -1;
}
*p1 = 20;
free(p1); //释放指针
int *p2 = new int(20);
delete p2;
int *p3 = (int *)malloc(sizeof(int) * 10); // 创建长度为10的数组,返回的是数组空间的首地址
if(p3==nullptr)
{
return -1;
}
free(p3);
int *p4 = new int[10](); // 创建长度为10的数组,返回的是数组空间的首地址
delete[] p4;
return 0;
}