一个神奇的问题(重新提问)

xtuzi 2005-11-11 11:12:20
因为上个帖子我发错了内容,后面补充了。但是很多人都没仔细看
所以我再这里再贴一遍好了,希望有人能解释,另外增加200分:

如果不信请做试验(VC 6.0):
======================================>
如果代码是
CString *p = new CString;
delete []p;
肯定是会出错的。这个运行时就知道了。
理论上也应该是要出错的。

=======================================>
但是如果是你自定义的类CMyClass那么
CMyClass *p = new CMyClass;
delete[]p;

这时并不会出错
-----------------------------------
如果你另外再加上下面的Test代码,在程序中却不调用Test
上面的delete []p就会出错了,我想知道到底是因为什么?

CMyClass *Test()
{
CMyClass *pp = new CMyClass [2];
return pp;
}

...全文
168 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
xtuzi 2005-11-11
  • 打赏
  • 举报
回复
的确是根析构函数有关的。
我觉得 codewarrior(会思考的草) 说的有道理:
如果我没有显式定义一对构造函数/析构函数,那么在什么情况下,编译器会帮你生成一对构造函数/析构函数?

femalelover 2005-11-11
  • 打赏
  • 举报
回复
这帖我顶了不是一两次了.
为什么一个没被调用的函数会使得本来可以通过的程序运行不起来呢?不解
wshcdr 2005-11-11
  • 打赏
  • 举报
回复
规定是new 与 delete,new [] 与 delete []配对使用的
违反了这个规定,就算能跑起来,也是不安全的
superjoel 2005-11-11
  • 打赏
  • 举报
回复
不明白你为什么要写成delete[]p
加[]是delete数组用的
把[]去掉应该就没问题了
xtuzi 2005-11-11
  • 打赏
  • 举报
回复
to wshcdr(dd) ,对,
像你那样,如果是一个完全的空类。就不会出问题。

这样问题比较明显了。
我查了一下,问题在于析构函数
如果有析构函数的话,这样就会出错了。
跟C++的实现机制有关系
Kudeet 2005-11-11
  • 打赏
  • 举报
回复
delete 后面的[]符号如果使用不配对,后果是不可预测的
wshcdr 2005-11-11
  • 打赏
  • 举报
回复
LZ,我下面的代码并没有报错
WIN2K + VC6 + SP5

class CMyClass
{

};

CMyClass *Test()
{
CMyClass *pp = new CMyClass [2];
return pp;
}

void CTest004Dlg::OnButton1()
{
// TODO: Add your control notification handler code here
CMyClass *p = new CMyClass;
delete []p;

}
xtuzi 2005-11-11
  • 打赏
  • 举报
回复
void CMyDlg::OnOk()
{
CMyClass*p = new CMyClass;
delete []p; //这个地方出不出错根有没有下面的Test函数很有关系
}

//实际上这个test是任何地方都不会调用到的。
CMyClass* Test()
{
CMyClass *pp = new CMyClass[10];
return pp;
}
Kudeet 2005-11-11
  • 打赏
  • 举报
回复
出错的代码是这样吗?
CMyClass *Test()
{
CMyClass *pp = new CMyClass [2];
return pp;
}
CMyClass *p = Test();
delete []p;
38062708 2005-11-11
  • 打赏
  • 举报
回复
等楼下来讲
hyamw 2005-11-11
  • 打赏
  • 举报
回复
如果你不自己定义构造函数/析构函数,编译器就自动帮你生成一个。
我这里有没有那个Test函数都会出错的(VC.NET 2003, xp sp2, debug方式)

出错停在
dbgheap.c的这个位置:
/*
* If this ASSERT fails, a bad pointer has been passed in. It may be
* totally bogus, or it may have been allocated from another heap.
* The pointer MUST come from the 'local' heap.
*/
_ASSERTE(_CrtIsValidHeapPointer(pUserData));


测试程序片段:
void CTestDlg::OnBnClickedOk()
{
CMyClass*p = new CMyClass;
delete []p;
}

CMyClass::CMyClass()
{
}

CMyClass::~CMyClass()
{
}

//头文件没有写出来,CMyClass类只有一个构造函数和一个析构函数。
我认为出错的原因就是在与你在释放内存的时候没有对应你new操作,不应该使用delete[]。在C++里面,使用delete释放对象的时候,会调用该对象的析构函数以便释放资源。而用delete[]的时候,编译器会认为你是在释放一个有多个对象组成的数组的内存,所以会重复多次调用这个对象的析构函数。具体调用几次,是由编译器在new操作过程中,在分配的内存中添加一定的边界标志(或者其他的什么手段,具体是什么我也不知道-_-b )来决定的。
在Debug版本中,这种问题有可能就体现不出来。用new XXX;的方式分配,用delete[] xx释放可能也不会出错,那是因为Debug版本中有相当的容错能力,以便在调试程序的时候不会导致系统当机。如果没有这个能力,估计我们调试程序就惨了,一会就得重新启动一次机器。
(以上观点只是个人看法,我也不知道对不对 :) )
至于femalelover(极品车神) 说的问题;
为什么一个没被调用的函数会使得本来可以通过的程序运行不起来呢?不解
我也不知道,估计是编译器的问题吧,反正我在.NET2003下运行的时候,有没有那个Test函数都会出错的。
lixiaosan 2005-11-11
  • 打赏
  • 举报
回复
好了,这个问题不深究了,
有人说得对,违反了这个规定,就算能跑起来,也是不安全的。

肯定的。。
new和delete要匹配。
xtuzi 2005-11-11
  • 打赏
  • 举报
回复
好了,这个问题不深究了,
有人说得对,违反了这个规定,就算能跑起来,也是不安全的。

16,551

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧