gpt4 book ai didi

c++ - 我试图访问 C++ 多态类的 vtable,但由于核心转储而失败,为什么?

转载 作者:行者123 更新时间:2023-11-28 00:00:23 25 4
gpt4 key购买 nike

我想用一个小程序来检测vtable的特性。我知道对于大多数流行的编译器,它们将生成其头部前导 size_t 的对象作为指向 vtable 的指针。所以我尝试转换这个指针并将其用于直接函数调用。

typedef void (*pf)();
struct C
{
virtual void f(){
printf("weird\n");
}
};
int main()
{
C c1;
C* p=&c1;
pf* pvtable=(pf*)p;
pf func1=pvtable[0];
(*func1)();
return 0;
}

我希望 (*func1)() 会打印出“weird”。但实际结果是核心转储。

我的程序哪里出错了?谢谢。

最佳答案

更新:

你这里有一个错误:

pf* pvtable=(pf*)p;

您正在将指向对象 C 的指针转换为指向 vtable 的指针。因此,您将 C 对象的内容解释为一个 vtable。相反,您需要更进一步地进行间接访问;将指向 C 的指针转换为指向 vtable 的指针并取消引用它:

pf* pvtable=*(pf**)p;

这样您将跟随存储在 C 对象开头的指针指向实际的 vtable。


我原来的答案重写了更多:

#include <iostream>

struct C
{
virtual void f()
{
std::cout << "weird" << std::endl;
}
};

typedef void** C_vtable;
typedef void (C_f)(C* thiz);

int main()
{
// Create the object on stack
C c1;

// Reinterpret its address to an address of a virtual table and dereference it.
C_vtable vtable = *reinterpret_cast<C_vtable*>(&c1);

// Pick the first pointer from the virtual table and reinterpret it as our function
C_f *func1 = reinterpret_cast<C_f*>(vtable[0]);

// Call it
(*func1)(&c1);

return 0;
}

这至少适用于 Linux 上的 gcc 和 clang,也可能适用于其他编译器。但它取决于实现!

关于c++ - 我试图访问 C++ 多态类的 vtable,但由于核心转储而失败,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39469150/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com