访问简单的vtable(虚函数表),不成功.我的程序错在哪里?

ewrewtq 2016-09-13 07:38:13
我想用一个小程序探索一个虚函数表的性质。
通常gcc/vc编译器都把多态对象的第一个函数作为虚函数表的指针。那么我把一个对象指针,强转成指向虚函数表(数组)的指针,再通过该指针来直接调用一个类的成员函数:

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;
}

运行到函数调用的这个语句的时候,程序core dump了。
我的程序错在哪里?
...全文
99 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2016-09-14
  • 打赏
  • 举报
回复
理解讨论之前请先学会如何观察! 计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构…… 对学习编程者的忠告: 多用小脑和手,少用大脑、眼睛和嘴,会更快地学会编程! 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步Debug版对应汇编一行! 单步Debug版对应汇编千行不如单步Release版对应汇编一行! 不会单步Release版对应汇编?在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有,然后在IDE中运行。(一般人我不告诉他!) VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
lm_whales 2016-09-13
  • 打赏
  • 举报
回复
每个编译器,对成员函数的实现方式,是不同的 因此,要针对具体编译器的具体版本,以及 编译配置(比如 32Bits,64Bits ) 和具体某一种类型的继承关系,(不是继承的,单一继承的,虚拟继承的,多继承的) 某个具体类,某个具体的虚函数。(数据类型,是否const 函数 等)做处理 才能按照, 函数指针方式,调用虚函数 但也不是完全准确的 很多功能是不能实现的。
mLee79 2016-09-13
  • 打赏
  • 举报
回复
x86 下成员函数缺省使用 thiscall, 你这函数原型就不对, 不过你这成员函数没访问任何成员变量, 也没有任何参数, 随便咋调用本来没啥问题的... 你访问虚表也不对, pf* pvtable= *(pf**)p;, 你少解引用一次.... 正常的代码应该是

#include <stdio.h>

#if defined(__i386__) && !defined(JJ_CALLTYPE)
#if defined(_MSC_VER)
#define JJ_CALLTYPE	__fastcall
#else
#define JJ_CALLTYPE __attribute__((fastcall))
#endif
#endif

#if !defined(JJ_CALLTYPE)
#define JJ_CALLTYPE
#endif

typedef void (JJ_CALLTYPE *pf)(struct C* j__thiz, int a, int b);
struct C
{
	C() : j___i(10) {}
	
    virtual void JJ_CALLTYPE f(int a, int b){
      printf("weird %d\n", a + b + j___i);
    }
	
	int  j___i;
};

int main()
{
    C c1;
    C* p=&c1;
    pf* pvtable= *(pf**)p;
    pf func1=pvtable[0];
    (*func1)(p, 100, 200);
    return 0;
}
paschen 版主 2016-09-13
  • 打赏
  • 举报
回复
成员函数其实还有个隐藏的参数就是指向对象的指针,所以你这样是会出错 其次,类中成员函数指针与普通函数指针是不同的

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧