C创建Lua嵌套表时整数取值异常问题求助
Lua嵌套表C实现整数数组赋值异常排查
需求与问题重现
需要创建的Lua嵌套表结构:
{ SA_1: {1,2,3,4}, SA_2: {11,22,33,44} }
为测试编写的C实现代码(将SA_2改为字符串类型):
int myRegisteredCfunc(lua_State *L) { // 原代码漏写参数,此处修正 lua_createtable(L, 0, 2); // 创建第一个内部表 lua_createtable(L, 0, 4); for (int i = 1; i < 5; ++i) { lua_pushinteger(L, i); // 推入对应整数值 lua_rawseti(L, -2, i); // 设置对应索引的值 } // 将第一个内部表设为外层表的SA_1字段 lua_setfield(L, -2, "SA_1"); // 创建第二个内部表 char test_str[20]; lua_createtable(L, 0, 4); for (int i = 1; i < 5; ++i) { sprintf(test_str, "str %d",i); lua_pushstring(L, test_str); // 推入对应字符串 lua_rawseti(L, -2, i); // 设置对应索引的值 } // 将第二个内部表设为外层表的字段(原代码拼写错误为SA2_2) lua_setfield(L, -2, "SA2_2"); return 1; // 原代码漏写分号,此处修正 }
运行后异常输出:
SA_1 (table): 4: 3 1: 4 2: 3 3: 3 SA_2 (table): 4: str 4 1: str 1 2: str 2 3: str 3
使用的Lua打印函数:
local table = LIB.myRegisteredCfunc() local function print_table(tbl, indent) indent = indent or 0 local spaces = string.rep(" ", indent) for k, v in pairs(tbl) do if type(v) == "table" then print(spaces .. k .. " (table):") print_table(v, indent + 1) else print(spaces .. k .. ": " .. tostring(v)) end end end print_table(table)
问题原因与解决方法
核心原因分析
- SA_1赋值异常直接原因:输出中SA_1的整数值混乱,大概率是实际代码中存在笔误——比如
lua_pushinteger的参数误写为固定值,或lua_rawseti的栈索引参数传错。原代码逻辑本身正确,但可能存在输入错误。 - 字段名拼写错误:原C代码中SA_2的字段名写成
SA2_2,与需求的SA_2不符。 - 打印遍历顺序问题:
pairs遍历Lua表不保证整数索引的顺序,导致输出时键的顺序混乱,但这不是值错误的原因。 - 表创建效率问题:创建以整数索引为主的内部表时,
lua_createtable的第一个参数(数组部分大小)应设为表的长度(如4),第二个参数(哈希部分大小)设为0,能让Lua更高效分配内存。
修正后的代码
修正后的C实现代码
#include <lua.h> #include <lauxlib.h> #include <stdio.h> int myRegisteredCfunc(lua_State *L) { // 创建外层表,哈希部分大小设为2(对应两个字段) lua_createtable(L, 0, 2); // 创建SA_1的内部表,数组部分大小设为4(对应4个整数索引) lua_createtable(L, 4, 0); for (int i = 1; i <= 4; ++i) { lua_pushinteger(L, i); // 将栈顶整数设为内部表第i个索引的值 lua_rawseti(L, -2, i); } lua_setfield(L, -2, "SA_1"); // 创建SA_2的内部表,数组部分大小设为4 char test_str[20]; lua_createtable(L, 4, 0); for (int i = 1; i <= 4; ++i) { sprintf(test_str, "str %d", i); lua_pushstring(L, test_str); lua_rawseti(L, -2, i); } // 修正字段名为SA_2 lua_setfield(L, -2, "SA_2"); return 1; }
优化后的Lua打印函数
使用ipairs遍历整数索引部分,保证输出顺序符合预期:
local table = LIB.myRegisteredCfunc() local function print_table(tbl, indent) indent = indent or 0 local spaces = string.rep(" ", indent) -- 先遍历整数索引(数组部分),保证顺序 for k, v in ipairs(tbl) do if type(v) == "table" then print(spaces .. k .. " (table):") print_table(v, indent + 1) else print(spaces .. k .. ": " .. tostring(v)) end end -- 再遍历非整数索引(哈希部分) for k, v in pairs(tbl) do if type(k) ~= "number" or math.floor(k) ~= k or k < 1 then if type(v) == "table" then print(spaces .. k .. " (table):") print_table(v, indent + 1) else print(spaces .. k .. ": " .. tostring(v)) end end end end print_table(table)
验证结果
运行修正后的代码,输出将符合预期:
SA_1 (table): 1: 1 2: 2 3: 3 4: 4 SA_2 (table): 1: str 1 2: str 2 3: str 3 4: str 4
内容的提问来源于stack exchange,提问作者ddomnik
相关产品推荐
相关产品推荐

