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

从一个笔误引起的思考

时间:2014-08-31 10:26:31      阅读:175      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   ar   数据   2014   div   问题   代码   

几天前组内一个同事做技术分享,其中谈到一个问题,如果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内存发现数据如下:

bubuko.com,布布扣

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

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

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

bubuko.com,布布扣

 

从一个笔误引起的思考

标签:style   blog   http   ar   数据   2014   div   问题   代码   

原文地址:http://www.cnblogs.com/mod109/p/3947370.html

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