C++ 如何避免双重删除?

C++ 如何避免双重删除?,c++,shared-ptr,delete-operator,C++,Shared Ptr,Delete Operator,有人能告诉我为什么在这里进行双重删除,以及我如何避免这种崩溃吗?只有程序退出时才会发生崩溃 #include <iostream> #include <string> #include <unordered_map> #include <memory> #include <conio.h> struct State; struct FlyweightStates { static std::unordered_map<

有人能告诉我为什么在这里进行双重删除,以及我如何避免这种崩溃吗?只有程序退出时才会发生崩溃

#include <iostream>
#include <string>
#include <unordered_map>
#include <memory>
#include <conio.h>

struct State;

struct FlyweightStates {
    static std::unordered_map<std::string, std::shared_ptr<State>> prototypes;
    static void insertPrototype (const std::string& tag, State* state) {
        prototypes.emplace(tag, std::shared_ptr<State>(state));
        std::cout << tag << " inserted in FlyweightStates::prototypes." << std::endl;
    }
};
std::unordered_map<std::string, std::shared_ptr<State>> FlyweightStates::prototypes;

struct State {
    virtual ~State() {std::cout << "State destructor called." << std::endl;  _getch();}
    State (const std::string& name) {
        FlyweightStates::insertPrototype(name, this);
    }
};

struct Sleeping : public State {
    static Sleeping prototype;
    Sleeping() : State("Sleeping") {}
};
Sleeping Sleeping::prototype;

int main() {}
此外,还包括以下内容:

struct FlyweightStates {
    static std::unordered_map<std::string, std::shared_ptr<State>> prototypes;
    static void insertPrototype (const std::string& tag, std::shared_ptr<State> state) {
        prototypes.emplace(tag, state);
        std::cout << tag << " inserted in FlyweightStates::prototypes." << std::endl;
    }
};
std::unordered_map<std::string, std::shared_ptr<State>> FlyweightStates::prototypes;

struct State {
    virtual ~State() {std::cout << "State destructor called." << std::endl;  _getch();}
    State (const std::string& stateName) {
        FlyweightStates::insertPrototype (stateName, std::shared_ptr<State>(this));
    }
};
如何避免双重删除?我无法从此使用共享\u。我需要flyweight存储器中的共享\u ptr。

使用共享\u ptr时,应立即从原始指针创建它,然后从该点开始忽略原始指针。如果使用相同的原始指针创建第二个共享\u ptr,则会得到第二个删除。您也不应该自己删除原始指针


不幸的是,您没有显示足够的代码来确切地知道问题所在。

程序将破坏映射中的相同状态,而静态变量则是程序的结尾

但真正的问题是您的状态是一个静态变量,您将其地址传递给一个共享的ptr。在它的生命周期结束时,shared_ptr不仅调用对象的析构函数,还试图释放它得到的指针。但是您的对象在静态存储中,释放静态存储区域中的对象无效

带走1:不要将未使用新创建的对象传递给共享的\u ptr

外卖2:用于创建共享指针

因此,在销毁共享的_ptr时会发生一次析构函数调用。 当C++运行时破坏静态睡眠原型时,调用另一个时间析构函数;p> 程序崩溃,因为shared_ptr的析构函数试图删除堆上未分配的指针

怎么办 若原型只包含静态对象,比如代码中的静态对象,那个么根本就不需要使用shared_ptr,因为这些对象将在程序退出时自动删除。将原型声明为


此外,如果您在代码中使用shared_ptr,我建议您为其创建一个typedef,这样您就可以轻松地将其更改为State*或任何其他您想要的指针类型。

这是一大堆代码,没有指示什么失败或在哪里失败。请提供更多详细信息。只有当程序退出时才会发生崩溃。@nvoigt这是一个完整的示例。双重破坏是因为您正在从指向静态对象的指针创建共享的\u ptr。在这种情况下,也许您可以使用一个空白的deleter;或者动态分配静态实例;或者重组flyweight管理器以创建对象本身,而不是非常危险地接受指向它希望使用new创建的对象的原始指针。@MikeSeymour在这种情况下使用shared_ptr有什么意义。在动态分配对象的情况下,空白删除程序将导致内存泄漏。只有当程序退出时才会发生崩溃。所以有两个所有者都认为他们拥有指针,但是我如何避免呢?我不能从中使用共享的\u。我的整个程序使用共享的\u ptr的状态对象,所以你确定以原始指针的形式存储原型状态是安全的吗?@prestokeys如果对象具有与代码中相同的静态存储持续时间,那么是的,原始指针可以。在堆栈上?真的吗?@LightnessRacesinOrbit不,不太好,谢谢
static std::unordered_map<std::string, State*> prototypes;
static std::shared_ptr<Sleeping> prototype;
...
std::shared_ptr<Sleeping> Sleeping::prototype(new Sleeping());