new和delete

sizeof 类似,new 和 delete 也不是函数,它们都是 C++ 定义的关键字,通过特定的语法可以组成表达式。

sizeof 不同的是,sizeof 在编译时候就可以确定其返回值,new 和 delete 背后的机制则比较复杂。

在实例解释 new 背后的机制之前,你需要知道 operator new 和 operator delete 是什么。

operator new operator delete

这两个其实是 C++ 语言标准库的库函数,原型分别如下:

void *operator new(size_t);     //allocate an object

void *operator delete(void *);    //free an object

void *operator new[](size_t);     //allocate an array

void *operator delete[](void *);    //free an array

后面的两个先不看,注意:上面的两个不是重载,只是函数名叫这个,operator new 申请内存之后不对内存进行初始化,直接返回申请内存的指针。

new delete 背后机制

 

class A *pA = new A(10);

new:

  1. 首先需要调用上面提到的 operator new 标准库函数,传入的参数为 class A 的大小,这里为 8 个字节,至于为什么是 8 个字节,也是未类型化的,
  2. 第二步就在这一块原始的内存上对类对象进行初始化,调用的是相应的构造函数,这里是调用 A:A(10); 这个函数,从图中也可以看到对这块申请的内存进行了初始化,var=10, file 指向打开的文件。
  3. 最后一步就是返回新分配并构造好的对象的指针,这里 pA 就指向 0x007da290 这块内存,pA 的类型为类 A 对象的指针。

delete:

  1. 调用 pA 指向对象的析构函数,对打开的文件进行关闭。
  2. 通过上面提到的标准库函数 operator delete 来释放该对象的内存,传入函数的参数为 pA 的值,也就是 0x007d290。

如何申请和释放一个数组?new[] delete[]

C++ 的做法是在分配数组空间时多分配了 4 个字节的大小,专门保存数组的大小,在 delete [] 时就可以取出这个保存的数,就知道了需要调用析构函数多少次了。

例如:class A *pAa = new A[3];

  delete []pAa;

这里要注意的两点是:

  • 调用析构函数的次数是从数组对象指针前面的 4 个字节中取出;
  • 传入 operator delete[] 函数的参数不是数组对象的指针 pAa,而是 pAa 的值减 4。

为什么 new/delete new []/delete[] 要配对使用?

??使用 new [] 用 delete 来释放对象的提前是:对象的类型是内置类型或者是无自定义的析构函数的类类型!

new/deletenew[]/delete[] 要配套使用总是没错的!

原文地址:https://www.cnblogs.com/Lune-Qiu/p/9331041.html