怎样判断一个指针指向的对象是否已经被析构?

bluesnow83 2005-03-23 05:33:27
我有需要用两个指针指向同一个对象,但是析构的时候会出问题。
有没有办法在析构前判断一下当前指针指向的内容是否还有效?
...全文
1171 29 打赏 收藏 转发到动态 举报
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
bluesnow83 2005-03-29
  • 打赏
  • 举报
回复
我的问题用其他的方法解决了,虽然对于这个问题没有得到最为直接的办法,不过还是学到了很多东西,谢谢大家
surstar 2005-03-24
  • 打赏
  • 举报
回复
指针delete了,好的方法是置为NULL
又学了点东西
tabris17 2005-03-24
  • 打赏
  • 举报
回复
tabris17(四不象):
你那个办法也是不行的,
CTest *ptr=new CTest(&IsValid);
我再来一个CTest *ptr1 = new CTest(&IsValid);呢?
一个对象释放所有对象都认为已析构了。


====================

每个对象都需要一个 IsValid 标识
ringphone 2005-03-24
  • 打赏
  • 举报
回复
tabris17(四不象):
你那个办法也是不行的,
CTest *ptr=new CTest(&IsValid);
我再来一个CTest *ptr1 = new CTest(&IsValid);呢?
一个对象释放所有对象都认为已析构了。
tabris17 2005-03-24
  • 打赏
  • 举报
回复
对象的指针仅仅是一个指向某块内存的指针而已

你不可能根据这块内存的内容来判断对象是否已经析构


必须使用一个存在于对象外部的标记来表示对象的生存期
ringphone 2005-03-24
  • 打赏
  • 举报
回复
可以增加一个管理类,对象的产生和释放都通过这个管理类,那就能解决了,只不过麻烦了一点。
其实我上面的方法修改一下给m_Valid置特殊值已经是相当安全的了,垃圾数据正好等于这个特殊值的可能性是相当小的,如果结合特殊情况,比如你的类是窗口类,置这个值是窗口句柄,然后通过IsWindow和向这个窗口发送自定义消息,窗口再返回一个特殊值来进行比对判断,那是百分百安全的。

当然最简单的办法是delete的时候加个try,catch
tabris17 2005-03-24
  • 打赏
  • 举报
回复
指向指针的指针是一种解决办法,不过不是我需要的,不知道还有没有更直接的办法,有没有人能确切的肯定这个问题没有确切的解决办法?
========================================


#include <stdio.h>

class CTest{
public:
CTest(bool *pIsValid)
{
*pIsValid=true;
m_pIsValid=pIsValid;
};
~CTest()
{
*m_pIsValid=false;
};
private:
bool *m_pIsValid;
};

bool IsValid;

int main()
{
CTest *ptr=new CTest(&IsValid);
delete ptr;

if(IsValid)
{
printf("对象还存在");
}else{
printf("对象已经析构");
}
return 0;
}

bluesnow83 2005-03-24
  • 打赏
  • 举报
回复
指向指针的指针是一种解决办法,不过不是我需要的,不知道还有没有更直接的办法,有没有人能确切的肯定这个问题没有确切的解决办法?
tabris17 2005-03-24
  • 打赏
  • 举报
回复
ASSERT_VALID(对象指针);
====

和IsBad*函数的效果是一样的,没用
lzzqqq 2005-03-24
  • 打赏
  • 举报
回复
ASSERT_VALID(对象指针);
tabris17 2005-03-24
  • 打赏
  • 举报
回复
只能用这个办法:


#include <stdio.h>

class CTest{
public:
int m;
};


int main()
{
CTest *handle=new CTest;

CTest** p1=&handle;
CTest** p2=&handle;
CTest** p3=&handle;

delete handle;
handle=NULL;

if(NULL!=handle)
{
(*p1)->m=100;
(*p2)->m=200;
(*p3)->m=300;
}else{
printf("对象已经析构");
}
return 0;
}
ringphone 2005-03-24
  • 打赏
  • 举报
回复
楼上的,谢谢提醒,确实是这样,那可以考虑给m_Valid赋一个特殊的值,比如0xEFEFEFEF,这样安全性就大大提高了。
tabris17 2005-03-24
  • 打赏
  • 举报
回复
ringphone(临风) ( ) 信誉:98 2005-03-24 09:17:00 得分: 0


前面提到的delete后p = NULL都是没用的。

..........................

==============================

你的方法也是无效的


由于对象已经被delete了,所以你无法保证在程序运行了一段时间后m_Valid的会被什么垃圾数据所覆盖



gorge_an 2005-03-24
  • 打赏
  • 举报
回复
楼上的方法看上去有效,我没有试过。不过大家要是使用Ref和UnRef机制可以大大的避免违规访问的问题了。
ringphone 2005-03-24
  • 打赏
  • 举报
回复
前面提到的delete后p = NULL都是没用的。

pa = new ClassA;
p = pa;
pb = pa;

delete p;
p = NULL;

这时pa,pb都不是NULL,再delete pa?

有一个办法:
class foo
{
public:
foo():m_Valid(TRUE){}
~foo(){m_Valid = FALSE;}
BOOL IsValid()
{
try
{
if(m_Valid)
return TRUE;
else
return FALSE;
}
catch(...)
{
return FALSE;
}
}

private:
BOOL m_Valid
};
coolaka 2005-03-24
  • 打赏
  • 举报
回复
同意楼上的
bobob 2005-03-24
  • 打赏
  • 举报
回复
同意楼上,那一系列函数我做过测试,是不行的.
那些函数只是判断程序对指针指的内容有没有操作权限,而delete后并没有没收权限,只是告诉操作系统这块内存可以分配给别的变量,在没有重新分配前,使用它和没有delete前一样

最好的办法,delete后p = NULL
tabris17 2005-03-23
  • 打赏
  • 举报
回复
回复人: DentistryDoctor(雅克医生<改行做程序员了>) ( ) 信誉:182 2005-3-23 17:37:33 得分: 0

IsBadCodePtr/IsBadHugeReadPtr/IsBadHugeWritePtr/IsBadReadPtr/IsBadStringPtr/IsBadWritePtr
系列

=============================================


你的方法也不可行。


对象一般会分配再两块地方,一个是栈内(普通声明),一个是在堆内(new出来的对象)。

前者由于分配在栈中,而栈内区域的内存永远是可执行(启用DEP的XP SP2系统除外)、可读写,所以
IsBad*系列函数根本无法判断。


new出来的对象是在堆内分配的,而堆的释放是由操作系统控制的,即使你delete了对象,并不代表此块内存已经不存在了,操作系统只是做了个删除标记而已,所以IsBad*系列函数也是无法判断的


tabris17 2005-03-23
  • 打赏
  • 举报
回复
对象的this指针是由调用者通过eax寄存器向对象传递的
-------------------
纠正:是ecx寄存器
tabris17 2005-03-23
  • 打赏
  • 举报
回复
to PigKing(猪皇) :

你的代码是不可行的。
对象的this指针是由调用者通过eax寄存器向对象传递的,而调用者根本不知道对象已经析构了

所以你的代码根本无法判断
加载更多回复(9)

16,472

社区成员

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

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

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