5

I'm working with Lua, which has a C API and its error raising functions use longjmps. When raising an error I first build a message describing what went wrong and then tell Lua to raise the error. For example

std::stringstream ss;
ss << "'" << function->cb->name << "' expects at most " << maxargs_all  
<< " argument(s) and received " << nargs;
luaL_error(L, ss.str().c_str());

It's my understanding that longjmp won't unwind the stack and so my stringstream object won't be destroyed. If I remember correctly, stringstream and other C++ library classes typically allocate data on the heap, which is freed when the object is destroyed. However, the destructor won't be called here and so I think this will result in a memory leak. Depending on the person who wrote the script, I could potentially be raising a lot of errors and thus leaking a lot of memory.

I'm sure other people have needed to solve a similar problem to this, but I can't find anything that's quite what I'm after. A lot of places say the objects won't get destroyed, but I would assume there must be a way to ensure the memory is freed?

user1520427
  • 1,345
  • 1
  • 15
  • 27
  • `ss.str().c_str()` Never, *ever* do this for *anything*, Lua-related or not. – Nicol Bolas Nov 26 '12 at 16:32
  • @NicolBolas Hmm, why's that? Does the `string` from `ss.str()` go out of scope before the call is actually made, thus potentially invalidating the c string? – user1520427 Nov 26 '12 at 21:09
  • Technically... no. But it's generally bad form; it's a pointer to the memory of a temporary. All manor of problems come from this sort of thing. – Nicol Bolas Nov 26 '12 at 21:20
  • 1
    @NicolBolas What kind of problems could occur that couldn't occur with a local variable? – user1520427 Nov 26 '12 at 21:59

1 Answers1

8

The solution is to compile Lua as a C++ library. Then luaL_error() will throw an exception instead of calling longjmp() and everything will be destroyed by stack unwinding.

Juraj Blaho
  • 13,301
  • 7
  • 50
  • 96
  • 2
    If the stack is unwound, doesn’t that also free the error message’s memory, leading to an invalid memory access? – Konrad Rudolph Nov 26 '12 at 08:35
  • @KonradRudolph Lua makes a copy of the message -- I think. – user1520427 Nov 26 '12 at 08:37
  • @KonradRudolph: I hope that the message is copied into the exception thrown same as if you throw an exception yourself (e.g.: `std::runtime_error()`). But I have not verified that. – Juraj Blaho Nov 26 '12 at 08:40