问题描述
#include <iostream>
class Base
{
public:
virtual void func0() { std::cout << "Base::func0" << std::endl; };
virtual void func1() { std::cout << "Base::func1" << std::endl; };
};
int main()
{
auto instance = Base();
uint64_t* vtableAddr = reinterpret_cast<uint64_t*>(&instance);
uint64_t* pVtable = reinterpret_cast<uint64_t*>(*vtableAddr);
auto func0 = reinterpret_cast<void(*)(Base*)>(*(pVtable + 0));
auto func1 = reinterpret_cast<void(*)(Base*)>(*(pVtable + 1));
func0(&instance);
func1(&instance);
auto func2 = reinterpret_cast<void(*)(Base*)>(*(pVtable + 2)); // exceed the limitation
func2(&instance); // core dump
}
我可以通过读取类首先 8 个字节(64 位编译器)来获取虚拟表地址。但是不知道有没有办法在运行时获取pVtable的最大合法偏移量。
如上例,如果我设置pVtable的offset为2,调用转换后的函数,会导致coredump。
每个类的虚拟表“大小”是否存储在任何位置?
解决方法
不能保证 vtable 存在,一旦您处理更复杂的继承(多个/虚拟和多个/虚拟的组合),您将非常失望。来自@Stephen Newell