delete对象后又能正常访问了

nalisaki 2011-05-18 06:55:04

A *a1,*a2;
a1 = new A();
a2 = a1;
double result = a1->add(34.5,22.2);
printf("result before delete = %f\n",result);
delete a1;
printf("A.ad = %d\n",a1->ad);

result = 0;
result = a2->add(232,22.2);
printf("result after delete = %f\n",result);

其中A的定义
class A
{
public:
A(){ad = 2;}
~A(){ad = 0;}
public:
int ad;
double add(double a,double b);
};


测试的结果是:当delete a1;之后,用a2访问还是照样可以执行,而且结果正确。
平台ms2008,好像人家说我的编译器有问题啊。不知道高手怎么解释?delete a1后,ad是乱码。
...全文
296 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
fengkakaxi 2011-12-04
  • 打赏
  • 举报
回复
c++ primer 原文如下(176页):
执行语句

delete p;

后,p变成没有意义。在很多机器上,尽管P没有定义,但仍然存放了他之前所指向对象的地址,然而P所指向的内存已经被释放,因此P不再有效。删除指针后,该指针变成悬垂指针。悬垂指针指向曾经存放对象的内存,悬垂指针往往导致程序错误,很难检测出来。

最佳实践:一旦删除指针所指的对象,立即将指针置为0。
KevinHo 2011-05-19
  • 打赏
  • 举报
回复
我认为,delete a1之后,这一块堆区的单元已经被标记为无效了,里边的值已经是很随机的值,可能是上一次使用后的残留值,这片存储区的使用由系统来决定。
另外,delete之后居然还能通过这个悬挂指针a1或者a2来访问原有的成员函数,这确实让人匪夷所思,居然没有报错,还能运行。
为了形成好习惯,再删除指针之后,其实应该将其赋值为0,或者NULL,意为将指针赋空,不指向任何对象
songguozhi 2011-05-19
  • 打赏
  • 举报
回复
这只能是在内存没有被再次利用之前才可以的
pengzhixi 2011-05-19
  • 打赏
  • 举报
回复
delete后将指针置为0就好了。
nalisaki 2011-05-19
  • 打赏
  • 举报
回复
这个只是一个测试,我看的其他人的一个工程中有这样模式,就是在多个类中引用了同一个指针,然后有一个类把这个指针(指向的对象)给delete了,我就想知道断然这样地删除,其他类中引用这个指针的后果。
nalisaki 2011-05-19
  • 打赏
  • 举报
回复
嗯,多谢大家,原来以为,delete之后,析构会调用这个没问题,还以为会马上进行内存回收呢。有运气成分。
pengzhixi 2011-05-19
  • 打赏
  • 举报
回复
玩火的后果就是某一天会伤着自己
fo1_sky 2011-05-19
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 qq120848369 的回复:]

C/C++ code
delete会析构+释放内存,如果析构函数可以忽略,那么对象的确没有变化,前提是内存没有被其他地方拿去使用.
[/Quote]
这个说的很有道理
hittyo 2011-05-18
  • 打赏
  • 举报
回复
这是因为你运气好而已,还是要记得将对象NULL比较保险
pcliuguangtao 2011-05-18
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 pathuang68 的回复:]

引用 4 楼 ljt3969636 的回复:

delete a1;之后会把a1内存标记为可重新分配,置于何时重新分配你不知道我也不知道系统自己知道,里面的值是否变化,你不知道我也不知道系统知道

但是你要知道,我也要知道
delete a1;
a1=NULL;
是个好习惯

++

delete后a1就成了一个dangling pointer,继续使用它会相当危险!
这……
[/Quote]

悬挂指针
天外来客-007 2011-05-18
  • 打赏
  • 举报
回复
1. a1,a2指向同一块内存,delete a1后,a1和a2指向的内存已经可以被再次使用,而不是a1和a2共同独有,你删除了a1,但是a1的值还指向这块内存,因此上可以使用,如果这是有其他的程序使用了这块内存,起结构就表示A的结构了,你再访问,可能会被拒绝;
2. 删除指针后,把指针的地址复位很关键,所以请删除内存后,把指向内存的指针设为NULL;
3.如果你使用两个指针指向了同一块内存,当要释放内存时,使用引用计数保证当已经没有指针指向该内存时才释放;

紫色动力 2011-05-18
  • 打赏
  • 举报
回复
[Quote=引用楼主 nacee 的回复:]
C/C++ code

A *a1,*a2;
a1 = new A();
a2 = a1;
double result = a1->add(34.5,22.2);
printf("result before delete = %f\n",result);
delete a1;
printf("A.ad = %d\n"……
[/Quote]

用delete删除动态分配的内存,就是把这块内存还给系统的,别的程序也能用它。但你的指针还是指向它。如果这块内存没有分配给别的程序,它就可能还是原来的值的。所以就出现了你delete后,还是原来的值。
wxf54318 2011-05-18
  • 打赏
  • 举报
回复
a2中保存的只是a1的引用,所以你这种存数巧合,程序不崩溃算你万幸
辰岡墨竹 2011-05-18
  • 打赏
  • 举报
回复
释放了对象,那么那个对象所在的堆内存只是标记了释放,如果没有立刻又别的东西分配堆里的东西并把它覆盖掉的话,那块内存还是原样,但是那样很不安全。
pathuang68 2011-05-18
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 ljt3969636 的回复:]

delete a1;之后会把a1内存标记为可重新分配,置于何时重新分配你不知道我也不知道系统自己知道,里面的值是否变化,你不知道我也不知道系统知道

但是你要知道,我也要知道
delete a1;
a1=NULL;
是个好习惯
[/Quote]
++

delete后a1就成了一个dangling pointer,继续使用它会相当危险!
这个说法很好
就想叫yoko 2011-05-18
  • 打赏
  • 举报
回复
delete后, 就不要再去访问它的数据成员了, 很可能崩溃掉
pearling 2011-05-18
  • 打赏
  • 举报
回复
你可以单步跟踪一下,观察一下delete那块内存以后,原来那块内存的变化:
被释放的指针的值没有变,而是指向的那块内存发生了变化,成了一堆乱码。这也就是我们说要养成良好的编程习惯,当delete以后要赋值为NULL,以避免“野指针”。
qq120848369 2011-05-18
  • 打赏
  • 举报
回复

指针是指针,内存是内存,指针=NULL不会对内存产生一丁点的影星啊.

你释放的是内存,不是释放指针.

内存被释放了,就不要再去碰它了.

永远让指针记住尚未被释放的内存地址,否则就是内存泄露.

内存被释放了,就让指针也忘记那个内存地址吧(=NULL),留着也没有用.
winginsky 2011-05-18
  • 打赏
  • 举报
回复
delete之后,要把指针赋值为NULL
至善者善之敌 2011-05-18
  • 打赏
  • 举报
回复
你这个纯属巧合、。。。。
加载更多回复(5)

64,691

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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