使用指针从 VTable 手动调用函数会导致分段错误

问题描述

手动调用 second() 函数时出现分段错误。我认为问题在于,当在 first() 中向前移动地址时,程序会丢失处理 D 函数在构造的 +1 类的内存中的位置的信息1}}。到目前为止,我还没有幸运地修复它。

int (*pfunSecond)(int) = (int (*)(int)) *(((void***)pb)[0] + 1);

解决方法

您的问题是:

  1. 您对 vtable 所做的一切都是未定义的行为。但我想您知道这一点,并且愿意接受。

我假设你的虚函数表布局是正确的;缺少特定的编译器,我别无选择。一元 import pandas as pd import numpy as np names1880 = pd.DataFrame({ 'Name': ['Walter','Roger','Jane','Imelda'],'Gender': ['Male','Male','Female','Female'],'Births': [100,200,120,220] }) gender_names,gender_codes = np.unique( names1880['Gender'],return_inverse=True ) print(gender_names) print(np.bincount(gender_codes,weights=names1880['Births'])) # ['Female' 'Male'] # [340. 300.] 似乎不确定,但我不知道 vtable 在您的系统上是如何布局的。

  1. 您的假成员函数指针上缺少隐式 this 指针。

  2. 您放弃了调用约定。

所以:

*

然后做 int (__cdecl *pfunFirst)(B*) = (int (__cdecl *)(B*)) *(((void***)pb)[0]); int (__cdecl *pfunSecond)(B*,int) = (int (__cdecl *)(B*,int)) *(((void***)pb)[0] + 1);

但我猜你的 vtable 布局实际上类似于

pfunFirst(b)

这仍然是 UB,但至少不包含 using cdecl_entry=void(__cdecl*)(void*); struct vtable_t{ cdecl_entry functions[1]; }; struct has_vtable{ vtable_t const* vtable; }; template<class R,class...Args>using cdecl_func=R(__cdecl *)(Args...); template<class Base,class R,class...Args> cdecl_func<R,Base*,Args...> get_vtable_entry(Base const* b,std::size_t n){ return reinterpret_cast<cdecl_func<R,Args...>(reinterpret_cast<has_vtable const*>(b)->vtable->functions[n]); } s

void***
,

不用仔细看,您是通过非成员函数指针调用这些成员函数(虚拟)。正在使用垃圾 this 指针调用函数。