c++虚继承,调用thunkfunc报错

问题描述 投票:0回答:0

我正在学习 C++ 类的对象模型,我在 ubuntu g++11 中做了如下演示:

#include <iostream>
using namespace std;

class B {
 public:
  B(int i = 1) : ib(i) {}
  virtual void f() { printf("B::f()\n"); }
  virtual void Bf() { printf("B::Bf()\n"); }
 private:
  int ib;
};

class B1 : virtual public B {
 public:
  B1(int i = 100) : ib1(i) {}
  virtual void f() { printf("B1::f()\n"); }
  virtual void f1() { printf("B1::f1()\n"); }
  virtual void Bf1() { printf("B1::Bf1()\n"); }
 private:
  int ib1;
};

using fn = void(*)(void);

int main() {
  B1 b1;
  size_t* vptr = *(size_t**)(&b1);
  size_t thunkAddr = vptr[7];
  fn thunkFunc = (fn)(thunkAddr);
  thunkFunc();
  // ((fn)(thunkAddr))();  <-- error occured: Segmentation fault (core dumped)
  return 0;
}

更重要的是,下面的代码也让我感到困惑:

int main() {
  B1 b1;
  size_t* vptr = *(size_t**)(&b1);
  printf("vb_offset   : %ld\n", *(vptr - 3));
  printf("top_offset  : %ld\n", *(vptr - 2));
  type_info* info = (type_info*)(*(vptr - 1));
  printf("typeinfo    : [name:%s, hash:%lx]\n", info->name(), info->hash_code());
  printf("call B1::f  : "); ((fn)(*(vptr + 0)))();
  printf("call B1::f1 : "); ((fn)(*(vptr + 1)))();
  printf("call B1::Bf1: "); ((fn)(*(vptr + 2)))();
  printf("padding     : %ld\n", *(vptr + 3));
  printf("vb_offset   : %ld\n", *(vptr + 4));
  printf("top_offset  : %ld\n", *(vptr + 5));
  info = (type_info*)(*(vptr + 6));
  printf("typeinfo    : [name:%s, hash:%lx]\n", info->name(), info->hash_code());
  // printf("B1::f[thunk]: "); fn thunk = (fn)(vptr[7]); thunk(); <-- Segmentation fault (core dumped)
  printf("call B::Bf  : "); ((fn)(*(vptr + 8)))();
  printf("--------------------------------------\n");
  printf("vptr from B : %p\n", vptr + 7);
  printf("vptr from B : %p\n", ((size_t**)(&b1))[2]);
  return 0;
}

但是当我使用“g++ -O test.cpp”而不是“g++ test.cpp”编译代码时,所有错误都消失了。

有人可以回答我的问题吗?非常感谢。

我使用了不同的方法来调用thunkfunc,下面的方法可以正常工作:

fn thunkFunc = (fn)(thunkAddr);
thunkFunc();

但另一种方法不起作用:

((fn)(thunkAddr))();
c++ segmentation-fault g++ virtual-inheritance thunk
© www.soinside.com 2019 - 2024. All rights reserved.