为什么在使用 memset 用零填充对象后,在 dynamic_cast 时出现异常

Mar*_*ark 2 c++ inheritance dynamic-cast memset memcpy

我正在用的dynamic_cast这个奇怪的运行时异常,但只有当我填的是我与使用零铸造的对象memset,或者只是一些数据复制到它memcpy。这是生成异常的示例。

class Base
{
public:
    virtual void func() { }
};

class Derived : public Base
{
public: 
    void func() override { }    
};

int main()
{   
    Derived derived;
    Base* base_ptr = &derived;
    memset(base_ptr, 0, sizeof(Derived));

    Derived* derived_ptr = dynamic_cast<Derived*>(base_ptr);    
}
Run Code Online (Sandbox Code Playgroud)

异常消息是:在此处输入图片说明

如果我Derived使用 memcpy将一个对象复制到另一个对象,我会得到相同的异常。任何人都知道发生了什么,是否弄乱了dynamic_cast使用的 RTTI ?

我正在制作一个游戏引擎,它是一个实体组件系统,在程序中的某个时刻,我从一个文件中加载了所有对象及其组件。我实现不同组件的方式是使用继承(每个组件都源自一个基本组件)。当我加载对象及其组件时,我不能只分配组件占用的内存量,我必须使用新的组件名称,因为只有这样 dynamic_cast 才能工作。

我正在使用 Visual Studio 2019。

Nat*_*ica 5

您的代码具有未定义的行为。 memset要求它设置的对象是TriviallyCopyable,你的不是因为它有虚函数。

这样做的结果是您正在覆盖编译器用于多态性的类中的数据,因此它无法解析强制转换,因为该信息现在是垃圾。

  • @Mark 不做`memset`?在不知道你实际上想要完成什么的情况下,这就是我所能建议的。 (3认同)