new与delete

对类类型而言,new运算是先分配内存再执行构造函数,delete是先执行析构函数再释放内存

对array的用法

我们都知道new与delete经常这样用:

1
2
3
4
5
int* 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
14
class 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

基类析构 0xe118d4

delete 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
2
Base* b = (Base*)malloc(12);
free(b);

12是随便指定的,结果不运行构造和析构函数,而且如果中间运行成员函数,程序会崩溃。 所以这种代码没有任何意义