我正处于从Lua接收一个字符串表的情况。我需要将字符串累积到一个数组中以调用内部C函数。字符串处理是函数范围的本地处理(即函数返回后不会对字符串保持引用)。
现在,我这样做:
int process_tokens(lua_State *lua)
{
char *tokens[TOKENS_MAX];
int ntokens = 0;
/* assume table at top */
while (ntokens < sizeof(tokens) / sizeof(*tokens)) {
lua_rawgeti(lua, -1, ntokens + 1);
if (lua_isnil(lua, -1))
break;
tokens[ntokens++] = luaL_checkstring(lua, -1);
lua_pop(lua, 1);
}
lua_pushnumber(lua, handle_tokens(tokens, ntokens));
return 1;
}
现在我的问题是:不在这里复制字符串是否安全?我倾向于认为是,因为包含它们的表不能被gc'ed直到process_tokens()
函数返回(假设它没有从堆栈中弹出),所以它包含的字符串不能太多。另一方面,我没有发现任何指示,当调用luaL_checkstring()
时指针获得的位置实际指向(对象内部?某处某种临时堆栈?)。
答案 0 :(得分:1)
如果你不复制这些角色,我认为你会惹麻烦。文档说,对于lua_tolstring
,&#34; 因为Lua有垃圾收集,所以不能保证lua_tolstring
返回的指针在从堆栈中删除相应的值后才有效&#34;从您的帖子中可以看出可能 char*
指向内存,该内存在表的生命周期内有效,但如果指针指向的是副本,该怎么办? Lua对象中的字符串?这将是令人惊讶的,但唯一确定的方法是查看Lua源代码。
不复制的另一个原因是寻找麻烦(意思是,它现在可以,但可能会在没有通知的情况下发生变化),是因为脚本中任何使您的假设无效的更改都会导致内存损坏,而不会发出任何警告。也就是说,当lua_ltostring返回的指针所指向的内存是gc&d;以及获取通知的聪明技巧,例如__del
元方法时,您的C代码甚至无法获得通知,会招致自己的表现惩罚)。
回到优化的基础知识:你真的担心辩论的字符串副本会在你的应用程序中成为瓶颈吗?因为如果没有,那就是过早的优化,并且当你忘记了所有关于这个无辜的&#34;快捷方式时,可能会导致一个非常费力的错误,从现在开始隔离一年。 :)