简体   繁体   中英

Read Access Violation From Using Smart Pointers

This problem has bugged me for several days now, and I just cant figure it out. What I am trying to do is get an Entity from the entityMap and make a copy of it. An Entity is essentialy a map of components, so I looped through each component and made a copy of it. I debugged the program, and it worked fine until the very last line, where it said "read access violation this was 0xFFFFFFFFFFFFFFF7." It was very strange as everything was initialized (I checked the debugger)

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);
    }

Here is the offending line

 newComponent->SetOwner(entity);

Here is all it does, setting the owner instance variable to the passed in parameter. That was where the debugger complained and sent me to file "memory" at _Decref method.

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

The problem here is that you can't copy objects just by copying the memory. For basic plain data objects without any constructors, destructors, or pointers this may work but for anything more complex it most likely won't.

For example, if the object contains pointers to data and these are released in a destructor then the data is not deep copied, rather the pointer is, and you get double free and also possible pointers to unallocated memory. If the object relies on something being done in the constructor it is never done when copying memory. And depending on how the size is calculated it may not even be a complete copy.

This is why you should always provide a cloning mechanism in the class that takes care of these issues in a way that suits the object and makes sure there's proper deep/shallow copying depending on the contents.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM