使用智能指针读取访问冲突

时间:2019-03-03 05:41:54

标签: c++

这个问题现在困扰了我好几天,我只是想不通。我想做的是从entityMap获取一个Entity并对其进行复制。实体本质上是组件映射,因此我遍历每个组件并制作了一个副本。我调试了程序,直到最后一行,它都说“读取访问冲突为0xFFFFFFFFFFFFFFFFF7”,该程序才能正常工作。一切都已初始化(我检查了调试器),这很奇怪

if (entityMap.find(classname) != entityMap.end()) {
    std::shared_ptr<Entity> & prefab = entityMap[classname];
    std::shared_ptr<Entity> entity = std::shared_ptr<Entity>(new Entity());
    for (auto & component : prefab->GetComponentMap()) {
        Component * compPtr = component.second.get();
        std::cout << compPtr->GetMemorySize() << "\n";
        size_t size = sizeof(compPtr->GetMemorySize());
        void * buffer = operator new(size);
        memcpy(buffer, compPtr, size);
        std::shared_ptr<Component> newComponent = std::shared_ptr<Component>(reinterpret_cast<Component *>(buffer));
        entity->AddComponent(newComponent);
        newComponent->SetOwner(entity);
    }

这是违规行

 newComponent->SetOwner(entity);

这就是所有操作,将所有者实例变量设置为传入的参数。那是调试器抱怨的地方,并通过_Decref方法将我发送到文件“内存”中。

void Component::SetOwner(std::shared_ptr<Entity> owner) {
    this->owner = owner;
}

1 个答案:

答案 0 :(得分:2)

这里的问题是您不能仅通过复制内存来复制对象。对于没有任何构造函数,析构函数或指针的基本普通数据对象,此可以起作用,但对于更复杂的事物,则很可能不起作用。

例如,如果对象包含指向数据的指针,并且这些指针在析构函数中释放,则不会对数据进行深度复制,而是对指针进行深度复制,这样您就可以获得双倍的空闲空间,并且还有可能指向未分配内存的指针。如果对象依赖于构造函数中正在执行的操作,则在复制内存时永远不会执行此操作。而且根据大小的计算方式,它甚至可能不是完整的副本。

这就是为什么您应该始终在类中提供一种克隆机制,以适合对象的方式处理这些问题,并确保根据内容进行适当的深/浅复制。