C++和C库使用longjmp

5

我正在使用Lua,它有一个C API和其错误引发函数使用longjmps。在引发错误时,我首先构建描述出错原因的消息,然后告诉Lua引发错误。例如:

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

据我理解,longjmp不会撤销栈,因此我的stringstream对象不会被销毁。如果我没记错的话,stringstream和其他C ++库类通常在堆上分配数据,在对象被销毁时释放。然而,在这里不会调用析构函数,所以我认为这将导致内存泄漏。根据编写脚本的人,我可能会引发很多错误,从而造成大量内存泄漏。
我确信其他人也需要解决类似的问题,但我找不到任何符合我要求的东西。许多地方说对象不会被销毁,但我认为必须有一种方法确保内存被释放?

永远不要为任何事情这样做,无论是与Lua相关还是不相关:ss.str().c_str() - Nicol Bolas
@NicolBolas 嗯,为什么?在实际调用之前,ss.str() 返回的 string 是否超出了作用域,从而可能使 c 字符串无效? - user1520427
从技术上讲...不是。但通常这是不好的形式;它是指向临时内存的指针。这种事情会带来各种问题。 - Nicol Bolas
1
@NicolBolas 什么样的问题可能会出现,而这些问题在使用本地变量时不会出现? - user1520427
1个回答

8
解决方案是将Lua编译为C++库。然后luaL_error()将抛出异常,而不是调用longjmp(),一切都将被堆栈展开销毁。

2
如果堆栈被解除,那么是否也会释放错误消息的内存,从而导致无效的内存访问? - Konrad Rudolph
@KonradRudolph Lua会复制这个消息——我想。 - user1520427
@KonradRudolph:我希望消息被复制到抛出的异常中,就像您自己抛出异常一样(例如:std::runtime_error())。但我还没有验证过。 - Juraj Blaho

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接