CPP游戏攻略03

前言

今天我们来谈一谈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++面向对象高级编程, 侯捷.

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

时间: 2024-10-14 04:37:54

CPP游戏攻略03的相关文章

2048 Puzzle游戏攻略

2048 Puzzle是当前很火的一款手机游戏.在地铁上会经常会看到有人在玩这个游戏. 首先,简单地介绍一下2048 Puzzle游戏.游戏的界面是一个4X4方格,每一个方格中可以放置一个数字.有四种移动数字的方法,向左.向右.向上.向下.当向一个方向移动时,所有的数字都会向这个方向移动,直到前面到了边界,或者有数字挡住.并且在移动方向,相连方格中相同的数字将会被合并.每次移动后,会随机在空白方格中出现2或者4数字,也有可能不出现. 成功条件:合出数字2048. 失败条件:所有方格中都有数字,并

贪吃蛇大作战游戏攻略

1.不去人群密集的地方 2.长大之后想要啥就有啥 3.跑马圈地,长大之后,要让身体占据更大的空间 4.不抢食物,头只在身体内运动,只有当外部空间比较大时再进行领土扩张 5.不抢食物,而是要围住食物之后慢慢吃. 6.对于进入身体内部的蛇,要压缩之,不停地围绕它转圈,每转一圈就压缩一点空间. 7.勿贪小利,要从地形上取胜,而不要注重一星半点的食物.要鲸吞小蛇,而不要与它们正面交锋 8.不行险,不侥幸,稳,慢.活着是第一要务,活着是一切之根本. 9.慎终如始,则无败事.

Codecombat 游戏攻略——JavaScript编辑语言——关卡(计算机科学三)Ⅱ

第21关:有用的对手 // 这片满是硬币的地方暗藏了致命的毒药. // 食人魔正在进攻,而差役尝试偷你的硬币! while (true) { var enemy = hero.findNearestEnemy(); if (enemy) { // 只在敌人类型不是 "peon" 的时候攻击. if (enemy.type != "peon") { hero.attack(enemy); } } var item = hero.findNearestItem(); i

攻略:游戏最致命的“票房毒药”

游戏的乐趣在于,设计者用各种"你猜不到"的规则和场景来征服玩家,而玩家则介于"我知道路"和"哎呀,又掉坑里了"的清晰与模糊之间摸索. 文/张书乐 原载于<人民邮电报>2016年5月27日<乐游记>专栏104期 从去年下半年开始,我就一直沉迷于一款经典日本动漫改编的卡牌手游,前些天,我的游戏热情却戛然而止.理由很"奇葩",因为我看到了一份游戏攻略,而且还不是完整版的游戏全程攻略,毕竟对于时下的网游而言,只

经典DOS游戏皇帝攻略(曾经的回忆)

最完美攻略>>>>> -------------------------------------------------------------------------------- 第一节:游戏的操作   游戏左上角圆圈为系统选项,包括离开(存储.读取)游戏.   游戏左上角圆圈为退离.   游戏右下角为皇帝状态表.   分别为智慧.武术.魅力.才艺和快乐/健康,寿命.体力   可选择小,显示为体力.   一开始游戏会做选择题,共20题左右,通过测试决定你的性格.特长,并打

xbox 360破解游戏下载攻略

xbox 360破解游戏下载攻略 可以按照游戏类型,游戏名称等条件进行查找. 不错不错,找到了很多好游戏德军总部 新秩序(Wolfenstein - The New Order)植物大战僵尸 花园战争 恶魔城 暗影之王真三国无双7合金装备崛起 复仇恶魔城 暗影之王 xbox 360破解游戏下载攻略,布布扣,bubuko.com

寒城攻略:Listo 教你 25 天学会 Swift 语言 - 03 The Basic

import Foundation //*********************************************************************************************** //1.The Basics(基础) //_______________________________________________________________________________________________ //介绍 //Swift 的类型是

安卓游戏上线必备攻略!怎么样在14天内接完16个大平台的SDK!

最近发现MDT推出去的系统的有不同问题,其问题就不说了,主要是策略权限被域继承了.比如我们手动安装的很多东东都是未配置壮态,推的就默认为安全壮态了,今天细找了一下,原来把这个关了就可以了. 安卓游戏上线必备攻略!怎么样在14天内接完16个大平台的SDK!

一个古老的编程游戏:Python Challenge全通攻略(转)

Python Challenge是一个网页闯关游戏,通过一些提示找出下一关的网页地址.与众不同的是,它是专门为程序员设计的,因为大多数关卡都要编程来算哦!! 去年和同学一起玩的,他做了大半,我做了小半,作弊了一些,33关全通,今天逛硬盘发现这个资料,拿出来晃晃. 非常非常非常非常好玩,强烈推荐编程的朋友都玩玩,不一定要会Python,我和我同学都不会,不过我们用C#一样能搞出来,没有障碍的. 0 http://www.pythonchallenge.com/pc/def/0.html 猜238,