#include <cstdio>
class baseclass
{
};
class derclass : public baseclass
{
public:
derclass(char* str)
{
mystr = str;
}
char* mystr;
};
baseclass* basec;
static void dostuff()
{
basec = (baseclass*)&derclass("wtf");
}
int main()
{
dostuff();
__asm // Added this after the answer found, it makes it fail
{
push 1
push 1
push 1
push 1
push 1
push 1
push 1
push 1
push 1
push 1
}
printf("%s", ((derclass*)basec)->mystr);
}
Run Code Online (Sandbox Code Playgroud)
Man*_*agu 10
啊.这是"不要做这个"的例子之一.在dostuff,您创建一个临时类型derclass,获取其地址,并设法将其传递到外部dostuff(通过分配basec).创建临时文件的行完成后,通过该指针访问它会产生未定义的行为.它的工作原理(即你的程序打印"wtf")肯定是平台依赖的.
为什么它在这个特定的实例中有效?要解释这一点需要深入研究而不仅仅是C++.您创建一个临时类型derclass.它存放在哪里?可能它被存储为堆栈中非常短暂的临时变量.你拿它的地址(堆栈上的一个地址),然后存储它.
稍后,当您去访问它时,您仍然有一个指向堆栈部分的指针.由于没有人来过并重复使用堆栈的那一部分,因此对象的残余仍然存在.由于对象的析构函数没有做任何事情来消除内容(毕竟,只是指向静态数据中存储的"wtf"的指针),你仍然可以读取它.
尝试插入在调用dostuff和printf调用之间占用大量堆栈的东西.比如说,调用一个factorial(10)递归计算的函数.我敢打赌,printf不再有效.
basec = (baseclass*)&derclass("wtf");
Run Code Online (Sandbox Code Playgroud)
在函数中遇到临时对象时derclass立即创建和销毁.因此,您的指针指向无效对象.;dostuff()basec
| 归档时间: |
|
| 查看次数: |
264 次 |
| 最近记录: |