Lua 5.3.5 unexpected table.insert behavior

Lua 5.3.5 unexpected table.insert behavior



When using table.insert(...) like this:


table.insert(...)


test =
table.insert(test, 1)
print(test[1]) -- 1

table.insert(test, 2)
print(test[1]) -- 1



The expected print result is



1



1



Now when you do this:


local A = b =
local B = c = x=0

function add(t, X)
local temp = B
temp.c = x=X
table.insert(t.b, temp)
end

local a = A
add(a, 1)
print(a.b[1].c.x) -- 1

add(a, 2)
print(a.b[1].c.x) -- 2



The result is



1



2



But shouldn't it be 1 and 1, too? This is my expected behavior, since I'm accessing the first element of the inner table b both times. What am I missing here?


b




2 Answers
2



I don't quite understand what you are trying to do with your code, but you get 2 instead of 1 that you expect because first and second elements point to the same table, so the modifications you think are applied only to the second element are actually applied to both (because of your local temp = B assignment, which makes B used in each of the inserted elements).


local temp = B


B



Add print(a.b[1] == a.b[2]) to the end of your script to confirm.


print(a.b[1] == a.b[2])






My code does certainly look confusing. In add(..) I am trying to create a new copy of B (here: temp) and add/insert it into the table A.b. How can I use B as something like a template? Thanks for the answer so far.

– user1511417
Sep 8 '18 at 9:13



add(..)


B


temp


A.b


B






You either need to deep copy it or change the code to make it a local assignment: local temp = c = x=0 (instead of local temp = B).

– Paul Kulchenko
Sep 8 '18 at 15:26


local temp = c = x=0


local temp = B



The problem is that Lua does not copy tables by values. You would need a deep copy-mechanism to copy really everything from a table. This code here works like expected while providing the requested 'defaults' of A and B.


A


B


function init_A(B)
local t =
if not (B== nil) then
t.b = B
else
t.b =
end
return t
end

function init_B(C)
local t =
if not (C== nil) then
t.c = C
else
t.c = x=0
end
return t
end

function add(t, X)
local temp = init_B(x=X)
table.insert(t.b, temp)
end

local a = init_A()
add(a, 1)
print(a.b[1].c.x) -- 1

add(a, 2)
print(a.b[1].c.x) -- 1
print(a.b[2].c.x) -- 2






Lua passes tables and full userdata as pointers.

– macroland
Sep 8 '18 at 23:53



Thanks for contributing an answer to Stack Overflow!



But avoid



To learn more, see our tips on writing great answers.



Required, but never shown



Required, but never shown




By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)