码迷,mamicode.com
首页 > 其他好文 > 详细

CPP游戏攻略03

时间:2019-01-19 00:47:27      阅读:189      评论:0      收藏:0      [点我收藏+]

标签:complex   形式   引用   创建   提高   编译器   ima   赋值   http   

前言

今天我们来谈一谈CPP中很关键的两个操作 new 和 delete ,关于他们与析构函数的关系、动态分配的内存空间、new array ( new[] ) 和 delete array ( delete[] ) 配套出现的原因以及我们可能产生误解的内存泄漏的形式。

与构造析构函数的羁绊

在一般 CPP 书中,作者都会告诉读者在调用 new 来动态创建一个对象时,会先分配空间,再调用构造函数。在调用 delete 回收空间时,会先调用析构函数,再释放内存。这里我引用第一篇攻略里的 complex 类,来深入了解其内部原理。

假设我们动态创建一个 complex 对象:

Complex *p = new Complex();

编译器会将其转化为三步:

Complex *p;

void *mem = operator new ( sizeof Complex ) ; // 1 分配内存
p = static_cast<Complex*> ( mem ) ;           // 2 类型转换
p->Complex::Complex(p) ;                      // 3 构造函数

第一步的 operator new 就是一个函数,内部会调用malloc(sizeof Complex)分配一块内存。
第二步进行类型转换,从 void 指针转为 Complex 指针。
第三步则调用 Complex 构造函数来为内存中的两个 double 赋值。其中传进去的 p 本身就是 this 指针,指向对象自己那一片内存。
技术分享图片

我们回收资源:

delete p;

编译器会转化为两步:

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

第一步调用析构函数,如果类的设计者有什么事情要在析构函数里干(比如释放成员指针指向的内存),那么就去干,没有则调用默认的析构函数。
第二步的 operator delete 同上也是一个函数,内存会调用free(p);来释放对应的内存。
技术分享图片

内存空间初探

当我们在调用 new 和 delete 时,内存空间究竟是怎么样的,认识这一点对于我们理解 new 和 delete 是很有帮助的,但是不同的编译器提高的方案略有不同,不过大体上的思想一致,本节就以 VC++ 编译器的做法来展示,g++ 类似。
给出两个例子:
技术分享图片
技术分享图片
其中头尾的 cookie 表示分配的内存块的大小,注意到图里不是写错了,而是 cookie 最低的一位表示这个内存块是被分配的内存块。除此之外,分配的内存块大小必须是16的倍数,这里说的是字节,所以16就是00000011。
在 delete 的时候,就是看的 cookie 的大小来释放内存,由 cookie 来显示大小,有 cookie 来释放内存块。

delete array

我们说 new array 和 delete array 就是 new[] 和 delete[] 。我们常说 new[] 必须由 delete[] 来收回空间,否则就会造成内存泄漏。那么是怎么个泄漏法呢?
首先来看一下 new[] 的内存块:
技术分享图片
技术分享图片
与 new 不同的是 new[] 会多出一个 field 来表示计数器,比如上面白色的部分,不过同样需要16字节对齐。
如果使用 delete[] 来回收内存,那么需要调用 n 次析构函数,再释放内存:
技术分享图片
但是只使用 delete ,那么只会调用 1 次析构函数,但是那一块内存同样释放了。再次提醒,内存释放需要看 cookie 大小,cookie是多大,就释放多大的空间。
技术分享图片
因此造成内存泄漏,实际上是没有调用足够次数的析构函数。所以我们知道,对于没有指针的类,光用 delete 来释放内存是完全 OK 的,但是有指针的类,会因为没有调用析构函数造成内存泄漏。

总结

我们发现,new[] 的内存块有时候不需要 delete[] 来配套使用,但是 new delete 一起使用,new[] delete[] 一起使用是基本素养。

Reference

C++面向对象高级编程, 侯捷.

CPP游戏攻略03

标签:complex   形式   引用   创建   提高   编译器   ima   赋值   http   

原文地址:https://www.cnblogs.com/trav/p/10289672.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!