有人可以在这里进行双重删除,以及如何避免这种崩溃?崩溃仅在程序退出时发生。
#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));
}
};
我该怎么做才能避免双重删除?我不能使用shared_from_this()。我需要flyweight存储中的shared_ptrs。
答案 0 :(得分:4)
因此,当shared_ptr
被销毁时,会发生析构函数的一次调用。
另一次在C ++运行时破坏static Sleeping prototype;
时调用析构函数。
程序崩溃是因为shared_ptr
的析构函数试图删除未在堆上分配的指针。
怎么做
如果prototypes
仅包含代码中的静态对象,则根本不需要使用shared_ptr
,因为这些对象将在程序退出时自动删除。将prototypes
声明为
static std::unordered_map<std::string, State*> prototypes;
如果prototypes
可以同时包含静态和动态对象,则表示它可以包含仅动态对象,因此也可以将Sleeping::prototype
设为shared_ptr
:
static std::shared_ptr<Sleeping> prototype;
...
std::shared_ptr<Sleeping> Sleeping::prototype(new Sleeping());
此外,如果您在整个代码中使用shared_ptr<State>
,我建议为其创建一个typedef,这样您就可以轻松地将其更改为State*
或其他任何您想要的指针类型。
答案 1 :(得分:1)
使用shared_ptr
时,应立即从原始指针创建它,然后忽略该点前的原始指针。如果使用相同的原始指针创建 second shared_ptr
,则会获得第二次删除。您也不应该自己删除原始指针。
不幸的是,您没有显示足够的代码来确切地知道问题所在。
答案 2 :(得分:0)
程序在地图中破坏相同的State
,静态变量破坏程序的结尾。
但真正的问题是你的状态是一个静态变量,你把它的地址传递给shared_ptr
。在它的生命周期结束时,shared_ptr
不仅会调用对象的析构函数,还会尝试释放它所获得的指针。但是您的对象在静态存储中并且释放静态存储区域中的对象是无效的。
带走1:不要将未使用new
创建的对象传递给shared_ptr
。
带走2:使用make_shared
创建共享指针。