对类类型而言,new运算是先分配内存再执行构造函数,delete是先执行析构函数再释放内存
对array的用法
我们都知道new与delete经常这样用:1
2
3
4
5int* a = new int(10);
delete a;
int* b = new int[10];
delete []b;
如果第二种情况改用delete b;
会不会有内存泄漏? 答案是仍然不会,分配简单类型内存时,内存大小已经确定,系统可以记忆并且进行管理,在析构时,系统并不会调用析构函数。它直接通过指针可以获取实际分配的内存空间,哪怕是一个数组内存空间。
但是对于类对象就不能这样用了,看下面的类:1
2
3
4
5
6
7
8
9
10
11
12
13
14class Base
{
public:
Base()
{
std::cout<<"基类构造 "<<this<<endl;
}
virtual ~Base()
{
std::cout<<"基类析构"<<this<<endl;
}
};
Base* pb = new Base[5];
delete pb;
运行结果如下,有5个构造,但只有1个析构函数,而且从this指针来看,是数组第一个元素的析构函数:1
2
3
4
5
6
7基类构造 0xe118d4
基类构造 0xe118ec
基类构造 0xe11904
基类构造 0xe1191c
基类构造 0xe11934
基类析构 0xe118d4delete pb
只用来释放pb指向的内存和一个析构。delete[] pb
用来释放指针指向的内存,还逐一调用数组中每个对象的析构。 所以为了编程规范,不管对简单类型还是类类型,都要用delete []pb
的形式。
与malloc/free的区别
new/delete
用于C++中的动态内存分配;malloc/free
仅用于C环境,用于类类型时,不会运行构造析构函数new/delete
不必指定分配内存大小,malloc/free
必须指定new返回的是指定对象的指针,而malloc返回的是
void*
,malloc
的返回值一般都需要进行类型转化。new是一个操作符可以重载,malloc是一个库函数
比如:1
2Base* b = (Base*)malloc(12);
free(b);
12是随便指定的,结果不运行构造和析构函数,而且如果中间运行成员函数,程序会崩溃。 所以这种代码没有任何意义