c中使用malloc出现的问题
- 程序员必须确定对象的长度
- malloc 返回一个
(void *)
指针 ,c++不允许将(void*)
赋值给其它指针,必须强转 - malloc可能申请内存失败,所以必须判断返回值来保存内存分配成功
- 用户在使用对象之前必须记住对他初始化,构造函数不能显示调用初始化(构造函数是由编译器调用的),用户有可能忘记调用初始化函数
c的动态内存分配函数太复杂,容易令人混淆,是不可接受的,c++中我们推荐使用运算符new和delete
new运算符和delete运算符
-
Person *p=new Person
会返回一个Person -
默认调用析构函数,开辟空间,返回不是
void*
,不需要强制转换 -
delete释放
-
new对象用
void *
取接受,释放不了对象 -
new出来的是数组,如何释放 ? delete[]
-
new出来的是数组,肯定会调用默认构造
#include<iostream> using namespace std; class Person { public: Person() { cout << "默认构造函数调用" << endl; } Person(int a) { cout << "有参构造调用" << endl; } ~Person() { cout << "析构函数调用" << endl; } }; void test01() { //Person p1; //栈区开辟 Person *p2 = new Person;//堆区开辟 //所有new出来的对象,都会返回该类型的指针 //malloc返回void*还要强转 //malloc会调用构造吗?不会 new会调用构造 //new运算符,malloc是函数 //释放堆区域的空间 //delete也是运算符,要配合new用,malloc配合free用 delete p2; } void test02() { void *p = new Person; //当用void* 接受new出来的指针,会出现释放的问题 delete p; //无法释放p } void test03() { //同过new来开辟数组 //一定会调用默认构造函数,所以一定要提供默认构造 Person *pArray = new Person[10]; //Person pArray2[2] = { Person(1), Person(2) };//在栈上开辟数组,可以指定有参构造 //释放数组 delete[]必须加上中括号 delete []pArray; } int main() { //test01(); //test02(); test03(); system("pause"); return 0; }
malloc/free和new/delete的区别
malloc/free和new/delete的共同点是:都是从堆上申请空间,并且需要用户手动释放。不同的地方是:
- malloc和free是函数,new和delete是操作符
- malloc申请的空间不会初始化,new可以初始化
- malloc申请空间时,需要手动计算空间大小并传递,new只需在其后跟上空间的类型即可
- malloc的返回值为void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型
- malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new不需要,但是new需要捕获异常
- 申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new在申请空间 后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理
- new/delete比malloc和free的效率稍微低点,因为new/delete的底层封装了malloc/free