从一个笔误引起的思考

几天前组内一个同事做技术分享,其中谈到一个问题,如果new出一个对象但是delete的时候,如果写成delete[]效果会如何。其中有同事在实际测试中发现如果是debug版本会抛异常,但是Release会反复执行该对象的析构函数。debug版本拋异常很容易理解,本来这么写就不对的,但是Release版本为什么会不断执行析构函数呢?如果是这样那又会执行多少次才会结束?笔者做了一下简单分析找到了其中原因,在解决这个问题之前我们先看看下面的代码和内存布局:

#include "stdafx.h"
#include <windows.h>

DWORDLONG g_dwTestCount = 0;
class CTest
{
public:
	~CTest()
	{
         ++g_dwTestCount;
	}

	int i;
};

int _tmain(int argc, _TCHAR* argv[])
{
	CTest *pTestAry = new CTest[10];
	delete[] pTestAry;

	CTest *pTest = new CTest;
	printf("%p\n",pTest);
	delete [] pTest;

	printf("%x",g_dwTestCount);
	getchar();
	return 0;
}

当程序执行过CTest *pTestAry = new CTest[10];,查看pTestAry内存发现数据如下:

前后cd部分就是系统分给用户的可用内存,其中红色标记的部分代表后面元素的个数,而delete[]的时候首先会读取这里的值,很明显的可以看出来在实际分配的堆内存中,往前4个自己代表分配元素个数;但是对new出来的单个对象却没有这个标识。但是如果说修改掉这个值会怎么样呢?通过实际测试,在delete之前直接把内存中的值修改掉,结果发现改成多少析构函数就执行多少次。

写到这里相信读者已经可以想到Release的情况,因为Release版本的堆结构和Debug版本有一定差别,在实际调试中并没有前后4个fd的情况。而之前的数字也并不固定,所以执行析构函数的次数也并非固定,但是考虑到目前4字节的无符号整形最大值是4294967295,所以执行次数也就在0到这个值中间`(*∩_∩*)′

附图:笔者用windbg截图出Release版本的执行结果和内存数据:

时间: 2024-08-08 22:05:53

从一个笔误引起的思考的相关文章

我是一个有点内向爱思考的人,学IT有一年时间了

我是一个有点内向爱思考的人,学IT有一年时间了.我主要是学php,asp这方面html,js,css,sqlserver,c#,mysql个人数据库 也都学了一些,我的优势是在学习期间做过和同学一起完成的商城网项目:“京东商城“,期间让我认识了网站架构模板和后台的强大也积累了不少做这类项目的经验.我对编程语言理解深刻,有很深的编程思想,自学能力强(属于实力派). 我的能力总结: 1.对微软系统的产品有较长时间的操作经验,3年的C#开发经验,项目包括公司进销存软件,人事管理软件以及公司年终抽奖软件

一个程序员正在思考问题的面部表情

一个程序员正在思考问题的面部表情

由一个emoji引发的思考

由一个emoji引发的思考 从毕业以来,基本就一直在做移动端,但是一直就关于移动端的开发,各种适配问题的解决,在日常搬砖中处理了就过了,也没有把东西都沉淀下来,觉得甚是寒颜.现就一个小bug,让我们来了解一下我们天天都在用的emoji,对于开发来说,是一个怎么样的存在. 背景 之前在做一个留言功能时,发现在其中一台安卓5.0的手机上,输入emoji糊掉了,成了如下这样的情况 这是skr啥玩意儿呀,怎么看上去像某白色幼虫. 与是我又试了好几个手机,ios都没有问题,甚至一台安卓机中之霸(安卓4.0

对于多个数据库表对应一个Model问题的思考

最近做项目遇到一个场景,就是客户要求为其下属的每一个分支机构建一个表存储相关数据,而这些表的结构都是一样的,只是分属于不同的机构.这个问题抽象一下就是多个数据库表对应一个Model(或者叫实体类).有了这个问题,我就开始思考在现有的代码中解决问题,最早数据采集部分是用EF来做数据存储的,我查了一下,资料并不多,问了一下对EF比较熟悉的朋友,得出的结论是EF实现这个功能比较复杂,不易实现.EF不能实现就要去找其他的框架,在PDF.NET的讨论群跟大家讨论这个问题的时候,@深蓝医生说PDF.NET可

对一个同事项目的思考和总结

这几天,跟旁边项目组的同事聊天,下班的时候也一起聊些项目上的事.通过他的描述和我看到的一些情况.确实发现不少问题的.首先就是上线成功率不高.很少有一次发布成功的情况.大部分都是发布之后,出现各种问题,又得改bug重发.开发和测试流程不规范,开发人员很随意.然后就是各种技术风险. 发布质量不高每次发布都跟打仗一样,每次上线发布,都要一两个小时,作为一个公司内部的web系统,一次小版本的更新,发布时间都要在1个小时以上,就足以说明很多问题. 发布质量不高 1. 发布的质量不高,没有进行系统的集成测试

从一个聊天信息引发的思考之Android事件分发机制

     转载请声明:http://www.cnblogs.com/courtier/p/4295235.html 起源:        我在某一天看到了下面的一条信息(如下图),我想了下(当然不是这个人问的问题)“为什么Activity能够与界面交互和为什么它们        的事件能够传递起来?”我带着这些疑问,自己上网查阅了一些资料与信息,从而得出以下的原理. Activity Window View 的关系:         我的归纳:众所周知,Activity并非是真正的显示对象.Ac

《像一个程序员一样思考》读后感

这学期,我阅读了由斯堡尔(V.Anton Spraul)写的<像程序员一样思考>这本书.事实上由于时间不是很充裕,我只认真的阅读了第一章,后面的章节我大致的浏览了一下.但是,仅仅通过第一章,我觉得这本书已经让我学到了很多的东西.因为这章中的很多东西我之前都没有认真的思考过.从整体上来看,我觉得这本书其实可以被看做是一本高级程序设计语言的教材.不过相比于我们所用的教材,这本书给了我很不一样的感觉,我想对这本书和我们的教材做一个对比. 我觉得这本书最大的特点是更加注重对于思想方法的培养,就像这本书

像一个程序员去思考

1.模块化: 如果大家玩过上古卷轴或者像其他一些单机游戏,添加mod到游戏中是一项非常有意思的事情, 可以让游戏的趣味性大大增加.但是添加这些mod并不容易,以上古卷轴为例,你需要一个 mod管理器,这是一个基本框架,除此之外还需要各种各种的插件,这个时候很多新手就会 抱怨:为什么不把这些软件都整合到一起,这样岂不是更容易,何必整的这么复杂呢. 这里的玩家就是软件用户,他们希望越简单越好.但是作为软件的开发者最重视的是软件开发的 难易程度以及软件的可维护性.因此,程序员们强调模块化,将一个软件项

一个小错误引发思考最终得出数组转字符串的新方法

今天在项目中犯了一个算得上是低级错误的错误吧 我在构造函数里声明了一个angle变量, this.angle; 然后在后面某函数中对此变量进行了+=操作, this.angle+=90 最后在一系列逻辑后我发现this.angle报错 NaN,马上定位到构造函数,就发现了原来该变量声明了但并未初始化赋值 求不笑,偶尔也是会傻乎乎犯些这种低级错误的,而这一次暴露出来完全是因为我在后面使用了+=操作,如果后面是单纯的 = 赋值操作,这样构造函数里是可以不初始化的 这时,我突然想试试如果+=后面不是数