You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

动态分配对象调用虚方法Core Dump:为何main中正常函数调用时崩溃?

虚函数调用崩溃问题分析

问题背景

以下代码中,main()里直接调用c->b.f()能正常输出"B",但将c->b传入fun()函数后调用b.f()会触发Core Dump,具体原因如下:

class A {
 public:
  inline virtual void f() const {printf("A\n");}
};

class B : public A {
 public:
  inline void f() const override {printf("B\n");}
};

class C {
 public:
  B b;
};

void fun(const B &b) {
  b.f();                         // coredump
}

int main() {
  C *c = (C*)malloc(sizeof(C));
  c->b.f();                      // print "B"
  fun(c->b);
  return 0;
}

核心原因

  1. malloc不执行构造函数:malloc仅负责分配内存空间,不会调用类的构造函数。对于带虚函数的类(比如继承了A的B),构造函数的关键作用是初始化虚表指针(vptr),让它指向类对应的虚表(vtable)。用malloc创建的对象,vptr是内存里的随机垃圾值。

  2. 直接对象调用的静态绑定优化:main()中c->b.f()是直接通过对象实例调用虚函数,且f()是inline函数。编译器会做去虚拟化优化,直接编译为静态调用B::f(),完全不需要访问虚表,因此哪怕vptr未初始化,也能正常执行。

  3. 引用调用的动态绑定要求:当把c->b传给fun()的const B&参数时,函数内的b.f()是通过引用调用虚函数。C++规定,通过指针/引用调用虚函数必须走动态绑定:通过对象的vptr找到虚表,再定位到目标函数地址。此时vptr是未初始化的垃圾值,访问该地址会触发非法内存访问,直接导致Core Dump。

解决方法

改用new创建C对象,new会自动调用C及成员B的构造函数,正确初始化虚表指针:

int main() {
  C *c = new C();
  c->b.f();
  fun(c->b);
  delete c;
  return 0;
}

内容的提问来源于stack exchange,提问作者brayden

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 04:45:30