простой пример кода, как показано ниже:
#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
}
Я могу получить адрес виртуальной таблицы, прочитав класс fisrt 8 байт (64-битный компилятор). Но я не знаю, есть ли способ получить максимально допустимое смещение pVtable во время выполнения.
Как и в приведенном выше примере, если я установлю смещение pVtable равным 2 и вызову преобразованную функцию, это приведет к coredump.
Где хранится размер виртуальной таблицы для каждого класса?