c++ - 为什么我在使用 memset 用零填充对象后在 dynamic_cast 处出现异常

标签 c++ inheritance memcpy dynamic-cast memset

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

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

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

我正在使用 Visual Studio 2019。

最佳答案

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

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

关于c++ - 为什么我在使用 memset 用零填充对象后在 dynamic_cast 处出现异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62071541/

相关文章:

c++ - SFML loadFromFile 不起作用,奇怪的错误

python - 鸭子类型(duck typing)与基于类的继承

c++ 公历和儒略历继承

c++ - 以下操作安全吗?

在 C 中创建动态字符串数组

c - 深层复制 - void** 的元素 - 结构体成员

c - 当我删除 "int e = 0;"时出现段错误

c++ - 如何通过命令行工具在 COIN-OR Cbc 中设置超时?

c++ - 此处不允许在 '{' 之前定义函数

c++ - 使用 dynamic_cast 转换 const 类