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

标签 c++ pointers polymorphism virtual vtable

我想用一个小程序来检测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/

相关文章:

c - 不确定如何正确使用 malloc() 和 free()

c++ - 指针和带指针的结构

java - 为什么组合可以动态选择类型

python - “损坏的双链表”内存错误 - OpenCV-Python 3.0.0 和 ARM 上的 Numpy

c++ - 将函数指针定义为新类型,并在 C++ 中将模板类型作为参数是不可能的吗?

c++ - 如何使用C++计算字符串中的特定单词

c++ - 执行 "delete this"时缺少虚拟析构函数

C++ 函数 = 删除

c++ - Vc++/c++ Force Include Header 异常

c++ - 如何定位一段时间内的某一系列汇编指令?