1

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).

arao6
  • 3,316
  • 5
  • 30
  • 51

1 Answers1

3

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_ptr you are doing a copy of the above class. The temporary is then discarded and things go boom.

So, first disable LuaState::operator=(LuaState const&) and LuaState(LuaState const&) constructor (make a private non-implemented version, or in C++11 delete it), or implement it.

Next, use make_shared<LuaState>() to create your shared_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?

Community
  • 1
  • 1
Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
  • Thanks! It no longer crashes immediately. The program has another odd but related problem. I have 2 Lua scripts, and both work fine when tested individually with std::vector. If I push_back both scripts, they both work for around 2 minutes and then the program crashes. It works fine when I run both scripts manually (by manually creating two Lua_State variables without a std::vector and "deleting" them manually). I'm lost as to why this may be happening. I am even checking if the shared pointer is valid (e.g. if (sharedPtr) { } ) – arao6 Dec 08 '12 at 20:39
  • @NicolBolas -- thanks for the edit. Was writing it on a smartphone with fat fingers. :) – Yakk - Adam Nevraumont Dec 11 '12 at 02:54