加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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不再有效.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读