1
votes

Some background: I'm tracking different hardware recourses in different Lua tables - for each hardware recourse I have a corresponding Lua table. To manage all the recourses I thought it makes sense to create a main table, and if a hardware recourse is free just set the correspondig table enty to nil.

The example below shows that a table seems to link an other table inside it as a referance; however, if I assign nil to a table key, only the key is set to nil and not the table itself as I actually hoped. (Refer to the output at the last 5 lines.)

local mainTable = {}
local subTable = {x = 123}

mainTable.subkey = subTable
print("The same value.")
print(mainTable.subkey.x)
print(subTable.x)
print("---")

print("The same value.")
mainTable.subkey.x = 456
print(mainTable.subkey.x)
print(subTable.x)
print("---")

print("Tables seem to have the same address.")
print(mainTable.subkey)
print(subTable)
print("---")

print("SubTable seems still to exist, even referance was set to nil")
mainTable.subkey = nil
print(mainTable.subkey)
print(subTable)
print(subTable.x)

Output:

The same value.
123
123
---
The same value.
456
456
---
Tables seem to have the same address.
table: 0x7f17a41596d0
table: 0x7f17a41596d0
---
SubTable seems still to exist, even referance was set to nil
nil
table: 0x7f4b48151710
456

Is it somehow possible to remove the intire content from the subTable without setting subTable = nil and mainTable.subkey = nil? (So finally the __gc methode of subTable is called.)

1

1 Answers

0
votes
local mainTable = {}
local subTable = {}

In this code you create two table variables. One is referred to by mainTable and one is referred to by subTable.

mainTable.subTable = subTable

Now we added another reference mainTable.subTable to the table which already has a reference subTable. So this table variable no has two references.

This line:

mainTable.subTable = nil

will only remove one of the two references. Hence subTable is still a valid reference to that table. As long as there are any references to that table, the garbage collector won't touch it.

In order to get rid of a table you have to remove all references. You cannot remove a table directly.