Unwanted and unexpected overwriting of tables

Hello,

This is almost certainly an incredibly basic problem but I’m picking up coding after a long, long absence.

The following is a very simplified version of a problem which keeps cropping up. The first bit of code works as I would expect.

[lua]


local A = 10

local B = A

A = A + 10

print(B)–> Console output: 10


[/lua]

So far, so expected, adding 10 to A has no effect on B.

However, if A and B are tables:

[lua]


local A = {10}

local B = A

A[1] = A[1] + 10

print(B[1]) --> Console output: 20


[/lua]

This, I don’t understand, why does the line A[1] = A[1] + 10 affect B?

In the problems I am trying to solve I often want to “store” a table, and perform actions on a copy of the table while keeping the stored table unchanged, however, in the same way as described above, these actions keep overwriting my stored table.

I’m assuming there is a common way of doing this and if anyone could let me know (a) what it is that I am fundamentally not getting here and ( B) how this sort of thing should be done, I would be very grateful.

Yours,

Jonathon.

You could do this:

----------------------------------------------- local A = 10 local Aa = {A} local B = A Aa[1] = Aa[1] + 10 print(B) --\> Console output: 10 print(Aa[1]) --\> Console output: 20 -----------------------------------------------

Hi Jonathon,

I think this has something to do with the way Lua handles the “equal sign” (=) operator. If you have assigned a simple value like an integer or a boolean to variable A, then creating a new variable B that is equal to A creates a “copy” of variable A’s value. However, if you assign variable A to a table, then entering “B = A” essentially just creates a new variable pointing to that same table. Here is a way to create a copy of a table instead of a new reference pointing to it:

[lua]

local function copyTable(t)

     local output = {}

     for k,v in pairs(t) do

          output[k] = v

    end

    return output

end

local a = {1, 2, 3}

local b = copyTable(a)

a[1] = a[1] + 1

print (a[1]) --> 2

print (b[1]) --> 1

[/lua]

There may be more elegant solutions, but this would work. Enjoy!

To expand on @schroederapp’s post.

When you create a table:   local a = {}

Then the “variable” a contains a pointer to the allocated memory for the table.  That’s why if you just print(a) you get something like 0x93483939, its the “address” of that memory.

When you assign a to b:   local b = a

then b now holds the same memory address as a, in effect creating an alias to the table.  You are not copying the table, you are copying the address of the table.

Rob

Thank you all for your replies, very useful.

schroederapps, thank you, your copyTable function is perfectly elegant enough for my needs.

Jonathon.

You could do this:

----------------------------------------------- local A = 10 local Aa = {A} local B = A Aa[1] = Aa[1] + 10 print(B) --\> Console output: 10 print(Aa[1]) --\> Console output: 20 -----------------------------------------------

Hi Jonathon,

I think this has something to do with the way Lua handles the “equal sign” (=) operator. If you have assigned a simple value like an integer or a boolean to variable A, then creating a new variable B that is equal to A creates a “copy” of variable A’s value. However, if you assign variable A to a table, then entering “B = A” essentially just creates a new variable pointing to that same table. Here is a way to create a copy of a table instead of a new reference pointing to it:

[lua]

local function copyTable(t)

     local output = {}

     for k,v in pairs(t) do

          output[k] = v

    end

    return output

end

local a = {1, 2, 3}

local b = copyTable(a)

a[1] = a[1] + 1

print (a[1]) --> 2

print (b[1]) --> 1

[/lua]

There may be more elegant solutions, but this would work. Enjoy!

To expand on @schroederapp’s post.

When you create a table:   local a = {}

Then the “variable” a contains a pointer to the allocated memory for the table.  That’s why if you just print(a) you get something like 0x93483939, its the “address” of that memory.

When you assign a to b:   local b = a

then b now holds the same memory address as a, in effect creating an alias to the table.  You are not copying the table, you are copying the address of the table.

Rob

Thank you all for your replies, very useful.

schroederapps, thank you, your copyTable function is perfectly elegant enough for my needs.

Jonathon.