c – 为什么这有效?这是一个小例子,但它甚至可以用于更复杂的项
发布时间:2020-12-16 10:54:08 所属栏目:百科 来源:网络整理
导读:#include cstdioclass 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
#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); } 解决方法
啊.这是“不要做这个”的例子之一.在dostuff中,你创建一个类型的临时类,获取它的地址,并设法将它传递到dostuff之外(通过将它分配给basec).创建临时文件的行完成后,通过该指针访问它会产生未定义的行为.它的工作原理(即你的程序打印“wtf”)肯定是平台依赖的.
为什么它在这个特定的实例中有效?要解释这一点,需要深入研究而不仅仅是C.您创建一个类型为derclass的临时类.它存放在哪里?可能它被存储为堆栈中非常短暂的临时变量.你拿它的地址(堆栈上的一个地址),然后存储它. 稍后,当您去访问它时,您仍然有一个指向堆栈部分的指针.由于没有人来过并重复使用堆栈的那一部分,因此对象的残余仍然存在.由于对象的析构函数没有做任何事情来消除内容(毕竟,只是指向静态数据中存储的“wtf”的指针),你仍然可以读取它. 尝试插入在dostuff和printf调用之间占用大量堆栈的东西.比方说,调用一个递归计算阶乘(10)的函数.我敢打赌,printf不再有效. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |