最新C/C++中的new和delete的实现过程小结

2022-06-27 11:48:40
目录
newdeletenew[]delete[]

下面是《C++ Primer 5th》中P726 对 new 和 delete 过程的解释:

当我们使用一条new表达式时,实际上执行了三步操作:

    new表达式调用一个名为 operator new (或者 operator new[] )的标准库函数。该函数分配一块足够大的、原始的、未命名的内存空间以便存储特定类型的对象(或者对象数组)。编译器运行相应的构造函数以构造这些对象,并为其传入初始值。对象被分配了空间并构造完成,返回一个指向该对象的指针。

    当我们使用一条delete表达式时,实际上执行了两步操作:

      对sp所指的对象或者arr所指的数组中的元素执行相应的析构函数。编译器调用名为 operator delete (或者 **operator delete[] **)的标准库函数释放内存空间。

      由于不同编译器对new的实现过程不同,所以我们下面以侯捷老师课件来进行详解。

      new

      假设我们现在有一个类:complex.h

      #ifndef __MYCOMPLEX__
      #define __MYCOMPLEX__
      
      class Complex {
      public:
      	Complex(double r = 0, double i = 0) :m_real(r), m_imag(i) {}
      	double real() const { return m_real; }
      	double imag() const { return m_real; }
      
      private:
      	double m_real;
      	double m_imag;
      };
      
      #endif
      

      我们new一个对象

      Complex* pc = new Complex(1,2);//Complex为类名(复数)
      

      编译器处理new这一语句的时候,先分配复数的内存,然后进行转型,最后调用构造函数,进行了下面三个过程

      void* men= operator new( sizeof(Complex));//第一步,分配内存
      pc = static_cast<Complex*>(men);//第二步,转型
      pc->Complex :: Complex(1,2);//第三步,调用构造函数
      

      下面是在VS2019上反汇编得到:

      请添加图片描述

      整体示意图如下:

      在这里插入图片描述

      delete

      当我们进行>

      delete pc;

      在编译器的处理过程中,这一语句转化两个步骤:先析构再free

      Complex::~Complex(pc);//析构函数
      operator delete(pc);//释放内存
      

      下面是在VS2019上反汇编得到:

      请添加图片描述

      示意图如下:

      在这里插入图片描述

      整体代码如下:

      int main() {
      	Complex* pc = new Complex(1, 2);
      	cout << pc->imag() << ":" << pc->real() << endl;
      	delete pc;
      	system("pause");
      	return 0;
      }
      

      整体程序运行结果如下:

      在这里插入图片描述

      new[]

      假设我们有一个类>

      #ifndef __MYSTRING__
      #define __MYSTRING__
      
      #include <string>
      
      class MyString {
      public:
      	MyString(const char* cstr = 0) {
              if (cstr) {
                  m_data = new char[strlen(cstr) + 1];
                  strcpy(m_data, cstr);
              }
              else {
                  m_data = new char[1];
                  *m_data = '\0';
              }
      	}
          ~MyString() {
              delete[] m_data;
          }
          char* get_c_str() const { return m_data; }
      private:
          char* m_data;
      };
      
      #endif
      

      我们new一个对象

      MyString* ps = new MyString("Hello");

      编译器处理new这一语句的时候,也是分为三个过程,与上相同

      void* men= operator new( sizeof(MyString));//第一步,分配内存
      ps = static_cast<MyString*>(men);//第二步,转型
      ps->MyString:: MyString("Hello");//第三步,调用构造函数

      下面是在VS2019上反汇编得到:

      请添加图片描述

      示意图如下:

      在这里插入图片描述

      delete[]

      当我们进行>

      delete ps;

      在编译器的处理过程中,这一语句转化两个步骤:先析构再free

      MyString::~MyString(ps);//析构函数
      operator delete(ps);//释放内存

      下面是在VS2019上反汇编得到:

      请添加图片描述

      请添加图片描述

      示意图如下:

      在这里插入图片描述

      整体代码如下:

      int main() {
      
      	MyString* ps = new MyString("Hello");
      
      	cout << ps->get_c_str() << endl;
      
      	delete ps;
      
      	system("pause");
      	return 0;
      }

      整体程序运行结果如下:

      在这里插入图片描述

      到此这篇关于C/C++中的new和delete的实现过程的文章就介绍到这了,更多相关C++ new和delete内容请搜索易采站长站以前的文章或继续浏览下面的相关文章希望大家以后多多支持易采站长站!