c++中的new与delete是为了申请动态内存空间和释放动态内存空间,下面对new和delete的用法,底层原理,与maclloc/free的区别以及定位new等进行说明.
1.用法
1.1.创建单个变量+释放
//语法格式
//创建单个变量
类型* 变量名=new 类型; //无初始化
类型* 变量名=new 类型(); //初始化成0
类型* 变量名=new 类型(内容); //自定义初始化
//释放单个变量
delete 变量名;
1.2.开辟一块连续的空间+释放
//语法格式
//开辟一块连续的空间
类型* 变量名=new 类型[元素个数]; //无初始化
类型* 变量名=new 类型[元素个数]{}; //所有元素初始化成0
类型* 变量名=new 类型[元素个数]{内容1,内容2}; //部分元素自定义初始化,剩下的元素初始化成0
//释放一块连续的空间
delete[] 变量名;
注意:①.开辟了一块空间后,一定要记得释放,否则会导致内存泄漏
②.释放空间时,如果释放的是一块连续的空间,要使用delete[]进行释放
如果是单个空间,使用delete释放即可
1.3.分别对内置类型和对自定义类型使用时的差别
当new对内置类型使用时,与malloc的作用相同
对自定义类型使用时,除了申请空间外,还会调用对应的构造函数
当delete对内置类型使用时,与free的作用相同
对自定义类型使用时,除了释放空间外,会调用对应的析构函数
2.底层原理
2.1.new的底层原理
new的底层是通过调用函数operator new来申请空间,而operator news是系统提供的一个全局函数,这个函数是对malloc的封装,包含判断申请空间是否失败的部分.
如果申请的空间类型是自定义类型,那么还会调用构造函数
2.2.delete的底层原理
delete的底层是通过调用函数operator delete来释放空间,而operator delete是系统提供的一个全局函数,这个函数是对free的封装,最终是使用free函数来释放空间
如果申请的空间类型是自定义类型,那么会先调用析构函数,再调用operator delete
2.3.new T[N]的原理
调用函数operator new[],在operator new[]中实际调用operator new函数完成N个对象的空间申请
如果申请的空间类型是自定义类型,那么还会调用N次构造函数
2.4.delete[]的原理
调用operator delete[]释放空间,实际在operator delete[]中调用operator delete来释放空间
如果申请的空间类型是自定义类型,那么会先调用N次析构函数,再调用operator delete[]
3.new/delete与malloc/free的区别
3.1.用法上的区别(new/delete简化用法)
①.malloc/free是函数,new/delete是关键字
②.malloc申请的空间不可以初始化,new申请的空间可以初始化
③.malloc申请空间时,需要手动计算空间大小,但new只需给空间的类型即可,如果是多个对象,在[]里指定对象个数即可
④.malloc的返回值是void*,在使用时必须强转,new不需要,因为new后面跟空间类型
⑤.malloc申请空间后要判断申请是否成功/失败,new不需要,因为new会抛异常
3.2.底层上的区别(new/delete解决自定义对象的初始化问题)
①.new/delete对自定义类型使用时,会调用对应的构造函数/析构函数,malloc/free不会
4.定位new(placement-new)
使用目的:对已经申请的没有初始化的内存空间调用构造函数进行初始化
使用格式:
new(place_address) type //第一种
new(place_address) type(initializer-list) //第二种
其中place_address必须是一个指针,initializer-list是用来初始化的参数
使用场景:
配合内存池使用(因为内存池分配出的内存没有初始化)
下面是一个使用例子:
//下面两行等价于new
Stack* ptr=(Stack*)operator new(sizeof(Stack));
new(ptr)Stack(4); //定位new
//下面两行等价于delete
ptr->~Stack();
operator delete(ptr);