【分享+搞笑】手动析构也会销毁自身的类

0153 2011-08-01 12:08:29
首先申明,该程序只在VC6下试验成功,其它地方情况未知。
主要是在类析构函数中添加自杀代码,一旦发现自己被直接调用就转自杀流程。
大家可以修改程序中的NOT_USE_DELETE=1或=0来看看直接调用析构函数和正常delete来看看运行结果。

#include "stdafx.h"

class A {
public:
A() {
m_pBuf = new int[10];
}
~A() {
__asm mov eax,[ebp];//取父函数的帧指针
__asm test [eax+8],1;//比较父函数的参数(VC6下是+8,其它未试验)
__asm jz _l_kill_this;//0表示直接调用了析构函数,转自杀流程
delete[]m_pBuf;//如果正常调用delete过来的,走正常析构流程
return;
_l_kill_this:
delete this;//自杀
}
int* m() {
return m_pBuf;
}
int n(int i) {
return m_pBuf[i];
}
private:
int* m_pBuf;
};

const int NOT_USE_DELETE = 1;
int main(void)
{
try {
A* pA = new A;
if (NOT_USE_DELETE) {
printf("直接调用析构函数\n");
pA->~A();
}
else {
printf("正常调用delete方法\n");
delete pA;
}
}
catch(...) {
printf("抛出例外\n");
}
getchar();
return 0;
}
...全文
326 29 打赏 收藏 转发到动态 举报
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
PG 2011-08-02
  • 打赏
  • 举报
回复
还是赞个吧,不过,你的程序假设太多了。
tompaz 2011-08-02
  • 打赏
  • 举报
回复
厉害,学习了
noodle123 2011-08-02
  • 打赏
  • 举报
回复
NOT_USE_DELETE为1时,第一次的时候崩溃,第二次又好了。
只是调用delete this后又走了一遍析构,难道这就是说明析构被直接调用了?
:析构时参数为0即为被直接调用,疑惑学习中。。。
noodle123 2011-08-02
  • 打赏
  • 举报
回复
我的在const int NOT_USE_DELETE = 1;时,会抛出异常,不知道咋回事,郁闷中。。。
nightkids_008 2011-08-01
  • 打赏
  • 举报
回复
我靠。。。。这俩天被这个玩晕了。。。
dingshaofengbinbin 2011-08-01
  • 打赏
  • 举报
回复
没什么意思啊,楼主来点新鲜的!
至善者善之敌 2011-08-01
  • 打赏
  • 举报
回复
真的可以吗?
至善者善之敌 2011-08-01
  • 打赏
  • 举报
回复
真的可以吗?
ryfdizuo 2011-08-01
  • 打赏
  • 举报
回复
lz 很闲啊。。
healer_kx 2011-08-01
  • 打赏
  • 举报
回复
。。。顶一下?
yshuise 2011-08-01
  • 打赏
  • 举报
回复
严格来说是错误的。
luciferisnotsatan 2011-08-01
  • 打赏
  • 举报
回复
顶一个
0153 2011-08-01
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 liufang421 的回复:]

原来如此,LZ 探索精神比N多动不动贴英文标准的星星可贵多了!

外面那贴还没完~

其实你试过你这个类

A a;
a.~A();

正常是不会崩溃的,
但是你这个如果跳进_l_kill_this的话...要不你试试?

我觉得析构函数除了 delete的时候会自动调用外,跟其他函数没啥区别~
总要想办法通过析构函数就把对象干掉,有什么意思~都接帖吧,100当散分了~……
[/Quote]
A a;
a.~A();
这个是会出错的,因为栈变量A a;本身就不需要delete,且其退出时会默认会析构一次,显然本例子是不支持的。
liufang421 2011-08-01
  • 打赏
  • 举报
回复
原来如此,LZ 探索精神比N多动不动贴英文标准的星星可贵多了!

外面那贴还没完~

其实你试过你这个类

A a;
a.~A();

正常是不会崩溃的,
但是你这个如果跳进_l_kill_this的话...要不你试试?

我觉得析构函数除了 delete的时候会自动调用外,跟其他函数没啥区别~
总要想办法通过析构函数就把对象干掉,有什么意思~都接帖吧,100当散分了~谢谢~
xp_c2010 2011-08-01
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 liufang421 的回复:]

单从流程上看,你就把手动调用析构函数屏蔽掉了;
相当于不管怎么都是在delete;


话说

mov eax,[ebp]
test [eax+8],1

这个方法你是怎么找到的....
[/Quote]那天楼主写的程序报错了,点忽略报错然后调试,跳出反汇编调试,他终于发现了原来还有这么个东西
0153 2011-08-01
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 liufang421 的回复:]

单从流程上看,你就把手动调用析构函数屏蔽掉了;
相当于不管怎么都是在delete;


话说

mov eax,[ebp]
test [eax+8],1

这个方法你是怎么找到的....
[/Quote]

我看了调用堆栈,这里无论是delete还是直接调用析构函数A::~A,VC实际上都是去调用A::`scalar deleting destructor()函数,该函数带一个参数x,内部实现是先调用~A,然后根据参数x(0或1)决定是否释放类实例本身的内存。所以关键就是在~A里找到父函数的参数x,因此mov eax,[ebp]是取得父函数的帧指针(也就是把父函数的ebp装入eax,然后[eax+8]就是父函数的第一个参数x)。以上在VC6、VC2005、VC2008下均试过,是一致的。
但是对于64系统,函数的第一个参数有可能是ebp+16的位置上,我没有条件测试,故结果不确定。
liufang421 2011-08-01
  • 打赏
  • 举报
回复
单从流程上看,你就把手动调用析构函数屏蔽掉了;
相当于不管怎么都是在delete;


话说

mov eax,[ebp]
test [eax+8],1

这个方法你是怎么找到的....
szqh97 2011-08-01
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 war10811 的回复:]

析构函数里基本不写东西的飘过
[/Quote]
++
yangyu1984 2011-08-01
  • 打赏
  • 举报
回复
理论上可以的吧~
Jxiaoshen 2011-08-01
  • 打赏
  • 举报
回复
围观。。
加载更多回复(9)

64,642

社区成员

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

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