经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C++ » 查看文章
最新C/C++中的new和delete的实现过程小结
来源:jb51  时间:2022/6/27 12:53:39  对本文有异议

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

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

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

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

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

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

new

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

  1. #ifndef __MYCOMPLEX__
  2. #define __MYCOMPLEX__
  3.  
  4. class Complex {
  5. public:
  6. Complex(double r = 0, double i = 0) :m_real(r), m_imag(i) {}
  7. double real() const { return m_real; }
  8. double imag() const { return m_real; }
  9.  
  10. private:
  11. double m_real;
  12. double m_imag;
  13. };
  14.  
  15. #endif

我们new一个对象

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

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

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

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

请添加图片描述

整体示意图如下:

在这里插入图片描述

delete

当我们进行 delete 操作时:

  1. delete pc;

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

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

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

请添加图片描述

示意图如下:

在这里插入图片描述

整体代码如下:

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

整体程序运行结果如下:

在这里插入图片描述

new[]

假设我们有一个类 MyString.h

  1. #ifndef __MYSTRING__
  2. #define __MYSTRING__
  3.  
  4. #include <string>
  5.  
  6. class MyString {
  7. public:
  8. MyString(const char* cstr = 0) {
  9. if (cstr) {
  10. m_data = new char[strlen(cstr) + 1];
  11. strcpy(m_data, cstr);
  12. }
  13. else {
  14. m_data = new char[1];
  15. *m_data = '\0';
  16. }
  17. }
  18. ~MyString() {
  19. delete[] m_data;
  20. }
  21. char* get_c_str() const { return m_data; }
  22. private:
  23. char* m_data;
  24. };
  25.  
  26. #endif

我们new一个对象

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

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

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

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

请添加图片描述

示意图如下:

在这里插入图片描述

delete[]

当我们进行 delete 操作时:

  1. delete ps;

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

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

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

请添加图片描述

请添加图片描述

示意图如下:

在这里插入图片描述

整体代码如下:

  1. int main() {
  2.  
  3. MyString* ps = new MyString("Hello");
  4.  
  5. cout << ps->get_c_str() << endl;
  6.  
  7. delete ps;
  8.  
  9. system("pause");
  10. return 0;
  11. }

整体程序运行结果如下:

在这里插入图片描述

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

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号