为什么我在使用memset将对象填充为0后,在dynamic_cast时出现异常?

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

我在使用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);    
}

异常信息是:enter image description here

如果我复制一个 Derived 对象到另一个使用memcpy.Anyone有什么想法,这是怎么回事,它是搞乱了RTTI该 dynamic_cast 的用途?

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

我使用的是Visual Studio 2019。

c++ inheritance memcpy dynamic-cast memset
2个回答
5
投票

你的代码有未定义的行为。 memset 要求它设置的对象是 可简单复制而你的类没有,因为它有虚拟函数。

这样做的后果是,你覆盖了编译器用于多态的类中的数据,因此它不能解析投值,因为这些信息现在是垃圾。


3
投票

一个有虚拟方法的类通常有一个 隐蔽 vtable的指针成员。 通过使用 memset 你正在破坏那个指针。

隐藏指针并不是C++语言规范所要求的,但它是目前实现虚拟方法和RTTI最常用的方式。

© www.soinside.com 2019 - 2024. All rights reserved.