#include <stdio.h>
#include <string.h>
#include <lua.hpp>
#include <vector>
static int Foo(lua_State *state);
static const luaL_Reg LuaMyLib[] = {
{"Foo", Foo}
};
int main()
{
lua_State *state = luaL_newstate();
for(int i = 0; i < sizeof(LuaMyLib)/sizeof(LuaMyLib[0]); ++i)
lua_register(state, LuaMyLib[i].name, LuaMyLib[i].func);
const char *script = "Foo()";
if(0 != luaL_loadbuffer(state, script, strlen(script), 0))
{
printf("%s\n", luaL_checkstring(state, -1));
lua_close(state);
return 0;
}
if (0 != lua_pcall(state, 0, LUA_MULTRET, 0))
printf("%s\n", luaL_checkstring(state, -1));
lua_close(state);
return 0;
}
int Foo(lua_State *L)
{
std::vector<char> buf;
buf.resize(1000);
//do something
//...
//shit happen!
luaL_error(L, "Foo() error!");
return 0;
}
廢話不多說,編譯後馬上用 valgrind 檢查...
疑!?在 luatest.cpp:35 出現了 memory leak?WTF!?這是為什麼呢?
因為呼叫 luaL_error() 處理錯誤時,Lua 使用 longjmp 產生類似 C++ exception 的效果脫離 VM,但 longjmp 並不會遵從 C++ stack unwinding 正確處理物件解構,也就是 luatest.cpp:34 產生的 vector 在離開 Foo() 時沒有呼叫 vector::~vector(),於是就遺失了 1000bytes!
要解決這個問題,用 C++ 的方式編譯 Lua 即可(把所有的 .c 改名為 .cpp),也由此可知 OS 幫我們安裝的 Lua lib 是 C 版本。
如果這個程式是放在 server side 整天不停執行,可預見的是在一段時間後一定會因為記憶體被消光導致系統崩潰,由此可見使用 valgrind 定期健檢的重要性!

沒有留言:
張貼留言