I haven’t used boost before, so forgive me if I am doing something silly. I have a class which holds a lua_State. I have a boost::shared_ptr vector which I push_back new states like so:
class Lua_State
{
lua_State *L;
std::string m_scr;
public:
Lua_State() : L(luaL_newstate())
{
lua_register(L, "test", test);
luaL_openlibs(L);
}
~Lua_State() {
lua_close(L);
}
inline bool LoadScript(const char* script)
{
if (!boost::filesystem::exists(script))
return false;
m_scr = fs::path(std::string(script)).filename().string();
chdir(fs::path(scr).parent_path().string().c_str());
if (luaL_loadfile(L, m_scr.c_str()))
return false;
// prime
if (lua_pcall(L, 0, 0, 0))
return false;
return true;
}
};
typedef boost::shared_ptr<Lua_State> LUASTATEPTR;
class Scripts
{
private:
std::vector<LUASTATEPTR> m_Scripts;
public:
Scripts() { }
void TestLoad()
{
m_Scripts.push_back(LUASTATEPTR(new Lua_State()));
LUASTATEPTR pState = m_Scripts[0];
pState->LoadScript("C:/test.lua");
}
};
The code works and the Lua state is added, but after a few seconds the application crashes. I am at a loss as to why this is happening. It works fine when I do it manually (without shared_ptrs and manually dereferencing).
You have violated the rule of 31. You created a non-trivial destructor and allocating constructor without disabling or writing a copy constructor and
operator=.Probably when you create the
shared_ptryou are doing a copy of the above class. The temporary is then discarded and things go boom.So, first disable
LuaState::operator=(LuaState const&)andLuaState(LuaState const&)constructor (make a private non-implemented version, or in C++11deleteit), or implement it.Next, use
make_shared<LuaState>()to create yourshared_ptr<LuaState>instances. This will create them “in place” and remove the copy.1 What is this Rule of 3 I speak of? See these links: Rule of Three (Wikipedia), What is the Rule of Three?