Array objects NEVER leave memor

Here’s my problem. No matter how many ways I try it, I cannot get this object from an array table to delete. I am not even posting my method of deletion because it’s just not working. This object includes an image, and is supposed to delete when it has left the screen. It doesn’t. I appreciate you help.

I’ve looked at dozens of documents, and have tried this for the last 5 hours…

local function loop()

    for i = #t, 1, -1 do

        local object = t[i]

        

        if object ~= nil then

        object.y = object.y + 5

end

   

        if object.y > 834 and object.y < 840 then 

          --I’VE TRIED DIFFERENT CODES HERE FOR HOURS. NEED REMOVAL CODE HERE

        collectgarbage()

        end

    end

end

Runtime:addEventListener(“enterFrame”, loop)

So, uhm, you’re not showing us the code you use, but we still have to tell you what’s wrong with it? :wink:

Show us your code and people will help. By the way, garbage collection does not happen instantly. Also, remove the displayobjects first, before removing the elements from the table. Then at the end remove the table.

Of course I can’t see if you’re already doing this or not.

Sorry, I wasn’t showing the code, because I was hoping somebody would know how to generally remove them. My “code” for trying removal has been about 50 different variations over the last 2 hours because I simply don’t comprehend what’s wrong :slight_smile:

I tried declaring something like

child = remove.table[t, i]

child = removeSelf()

child = nil

I tried it with object instead, I tried doing a for, do loop on it, and a million other things

The cubes would reappear on top as I meant them to, but one would always be slightly off on the x axis, then the next one would be slightly off, then the next.

Also, memory kept building up because the images weren’t deleting.

I wouldn’t program a frame event that way, nor would I remove elements from an array while looping through the array as it can cause some serious issues.

But given what you are doing can’t you just say something along the lines of

 if object.y \> 834 and object.y \< 840 then t[i]:removeSelf() t[i] = nil collectgarbage() end

or something along these lines.

local function loop() local tmpArray = {} for i = #t, 1, -1 do local object = t[i] if object ~= nil then object.y = object.y + 5 end if object.y \> 834 and object.y \< 840 then tmpArray[#tmpArray + 1] = {index = i} end end for i = 1, #tmpArray do if (t[tmpArray[i].index] ~= nil) then t[mpArray[i].index]:removeSelf() t[mpArray[i].index] = nil end end tmpArray = nil end Runtime:addEventListener("enterFrame", loop)

Still having my first cup of cafe though :slight_smile:

Okay. First of all, if you’re looping backwards through a table, in my opinion it’s okay to delete elements. I do it all the time.

Secondly, do something like this, in this order:

myTable[i]:removeSelf() table.remove[myTable,i]

Thirdly, don’t call your table “table”. Call it myTable of something else, but not table.

Fourth, call garbage collection only once, after the loop is completed, or don’t call it at all. Corona will collect when necessary automatically - no need to call this yourself unless you’re testing memory. If you really want to call it, do this outside of the loop.

Fifth, I’m not sure wether or not you need to state myTable[i] = nil inbetween the removeSelf and remove statements. Try both and see which works.

Sixth, I’m assuming you remove an object when it passes a certain Y location. Use only “object.y > 834” as this should be enough, if I’m not mistaken (I am making assumptions here), and adding the “and object.y < 840” will only make your loop slower.

lol good catch didn’t even see that he had a -1 on that loop :slight_smile:

On your fifth statement he does need to myTable[i] = nil 

They both work like a charm thank you gents :slight_smile:

Just one last question, here is what I ended up using. The stuff in bold is part of the code that I hadn’t included before. Basically it’s lines of cubes that go down, and once they reach the bottom they dissapear. You guys helped me with that, but I want them to reappear at the top, and change pictures…I tried calling the createCube1() on various places within the loop, but this increases and even multuplies the memory sometimes. Do guys have any suggestions on how to implement this? 

myTable= {}

-----------CREATE ROW 1

for i = 1, 7, 1 do

square1 = display.newImageRect( images[math.random(1,9)], cubeDimension, cubeDimension)

square1.x = cubeDimension * (i)

square1.y = screenH - halfCube - (cubeDimension) 

table.insert(myTable, square1)

end

------------ROW 2 Higher on the Y axis

for i = 1, 7, 1 do

square1 = display.newImageRect( images[math.random(1,9)], cubeDimension, cubeDimension)

square1.x = cubeDimension * i

square1.y = screenH - halfCube - (cubeDimension*2) 

table.insert(myTable, square1)

end

--------------ROW 3

for i = 1, 7, 1 do

square1 = display.newImageRect( images[math.random(1,9)], cubeDimension, cubeDimension)

square1.x = cubeDimension * i

square1.y = screenH - halfCube - (cubeDimension*3) 

table.insert(myTable, square1)

end

----------ROW 4

for i = 1, 7, 1 do

square1 = display.newImageRect( images[math.random(1,9)], cubeDimension, cubeDimension)

square1.x = cubeDimension * i

square1.y = screenH - halfCube - (cubeDimension*4) 

table.insert(myTable, square1)

end

-----------function to create new line of cubes  (it works, it’s just increasing memory probably because I’m not calling it in the right place)

function createCube1()

for i = 1, 7, 1 do

square1 = display.newImageRect( images[math.random(1,9)], cubeDimension, cubeDimension)

square1.x = cubeDimension * i

square1.y = screenH - halfCube - (cubeDimension*4) 

table.insert(myTable, square1)

end

end

–boolean to help with above function

createCube = false

-----the…LOOP

local function loop()

    for i = #myTable, 1, -1 do

        local object = myTable[i]

        

        if object ~= nil then

        object.y = object.y + 5

end

   

        if object.y > 834 then 

        myTable[i]:removeSelf()

table.remove(myTable,i)

object:removeSelf()

        end

    end

end

Runtime:addEventListener(“enterFrame”, loop)

Never mind, its pretty obvious, call the createcube () OUTSIDE the loop DUH! Been programming for more that 16 hours so I’m fried! Thanks again!

By the way, here are some extra pointers for removing your objects from the table:

  1. Do not nil the object if you’re using table.remove(), as table.remove() automatically deletes the object when finished. Setting it to nil will end up setting the object  after it to nil, because table.remove() takes the element out and “re-stacks” the table behind it.

Visual explanation (complete with beautiful hand-authored ASCII art :D):

[EDIT:] *Sigh*… It doesn’t look so good on the forum software :frowning:

[lua]

  •                                                                                               +

  •                              + + + + + + + + + + + + + +                                      +

  •                              + Say, perchance, that we +                                      +

  •                              + should remove t[i] now: +                                      +

  •                              + + + + + + +|+ + + + + + +                                      +

  • Iteration (i = x):                        V                                                   +

  • --------------------------------------------------------------------------------------------- +

  • Original  |  #t  |  #t - 1  |  #t - 2  |  table.remove(t[i])  |  t[i] = nil                   +

  • --------------------------------------------------------------------------------------------- +

  • A         |  A   |  A       |  A       |  A                   |  A                            +

  • B         |  B   |  B       |  B       |  B                   |  B                            +

  • C         |  C   |  C       |  C       |  C                   |  C                            +

  • D         |  D   |  D       |  D       |  D                   |  D                            +

  • E         |  E   |  E       | <E>      |  F <- E removed      |  [F] <- F is now nil, not E   +

  • F         |  F   |  <F>     |  F       |  G                   |  G                            +

  • G         | <G>  |  G       |  G       |                      |                               +

[/lua]

  1. As thomas6 said, don’t go crazy with the garbage collecting. Because of the way Lua works, you don’t ever need to call it manually, unless you need to gauge your memory or quickly compensate for a memory warning.

  2. You should use display.remove() over :removeSelf(), because display.remove() does nil checking, while :removeSelf() will throw an error if the object doesn’t exist (attempting to index local ‘obj’ (a nil value) )

[lua]

display.remove(object)

[/lua]

Also important: When deleting objects from an (indexed) table, you should use table.remove(), not t[i] = nil, because simply nil-ing out the object leads to problems with iteration. Using the length operator (#) on it ends up as the lowest non-nil value, so you end up with almost un-findable bugs.

Hope this helps :slight_smile:

  • Caleb

Got it! Thanks :slight_smile:

So, uhm, you’re not showing us the code you use, but we still have to tell you what’s wrong with it? :wink:

Show us your code and people will help. By the way, garbage collection does not happen instantly. Also, remove the displayobjects first, before removing the elements from the table. Then at the end remove the table.

Of course I can’t see if you’re already doing this or not.

Sorry, I wasn’t showing the code, because I was hoping somebody would know how to generally remove them. My “code” for trying removal has been about 50 different variations over the last 2 hours because I simply don’t comprehend what’s wrong :slight_smile:

I tried declaring something like

child = remove.table[t, i]

child = removeSelf()

child = nil

I tried it with object instead, I tried doing a for, do loop on it, and a million other things

The cubes would reappear on top as I meant them to, but one would always be slightly off on the x axis, then the next one would be slightly off, then the next.

Also, memory kept building up because the images weren’t deleting.

I wouldn’t program a frame event that way, nor would I remove elements from an array while looping through the array as it can cause some serious issues.

But given what you are doing can’t you just say something along the lines of

 if object.y \> 834 and object.y \< 840 then t[i]:removeSelf() t[i] = nil collectgarbage() end

or something along these lines.

local function loop() local tmpArray = {} for i = #t, 1, -1 do local object = t[i] if object ~= nil then object.y = object.y + 5 end if object.y \> 834 and object.y \< 840 then tmpArray[#tmpArray + 1] = {index = i} end end for i = 1, #tmpArray do if (t[tmpArray[i].index] ~= nil) then t[mpArray[i].index]:removeSelf() t[mpArray[i].index] = nil end end tmpArray = nil end Runtime:addEventListener("enterFrame", loop)

Still having my first cup of cafe though :slight_smile:

Okay. First of all, if you’re looping backwards through a table, in my opinion it’s okay to delete elements. I do it all the time.

Secondly, do something like this, in this order:

myTable[i]:removeSelf() table.remove[myTable,i]

Thirdly, don’t call your table “table”. Call it myTable of something else, but not table.

Fourth, call garbage collection only once, after the loop is completed, or don’t call it at all. Corona will collect when necessary automatically - no need to call this yourself unless you’re testing memory. If you really want to call it, do this outside of the loop.

Fifth, I’m not sure wether or not you need to state myTable[i] = nil inbetween the removeSelf and remove statements. Try both and see which works.

Sixth, I’m assuming you remove an object when it passes a certain Y location. Use only “object.y > 834” as this should be enough, if I’m not mistaken (I am making assumptions here), and adding the “and object.y < 840” will only make your loop slower.

lol good catch didn’t even see that he had a -1 on that loop :slight_smile:

On your fifth statement he does need to myTable[i] = nil 

They both work like a charm thank you gents :slight_smile:

Just one last question, here is what I ended up using. The stuff in bold is part of the code that I hadn’t included before. Basically it’s lines of cubes that go down, and once they reach the bottom they dissapear. You guys helped me with that, but I want them to reappear at the top, and change pictures…I tried calling the createCube1() on various places within the loop, but this increases and even multuplies the memory sometimes. Do guys have any suggestions on how to implement this? 

myTable= {}

-----------CREATE ROW 1

for i = 1, 7, 1 do

square1 = display.newImageRect( images[math.random(1,9)], cubeDimension, cubeDimension)

square1.x = cubeDimension * (i)

square1.y = screenH - halfCube - (cubeDimension) 

table.insert(myTable, square1)

end

------------ROW 2 Higher on the Y axis

for i = 1, 7, 1 do

square1 = display.newImageRect( images[math.random(1,9)], cubeDimension, cubeDimension)

square1.x = cubeDimension * i

square1.y = screenH - halfCube - (cubeDimension*2) 

table.insert(myTable, square1)

end

--------------ROW 3

for i = 1, 7, 1 do

square1 = display.newImageRect( images[math.random(1,9)], cubeDimension, cubeDimension)

square1.x = cubeDimension * i

square1.y = screenH - halfCube - (cubeDimension*3) 

table.insert(myTable, square1)

end

----------ROW 4

for i = 1, 7, 1 do

square1 = display.newImageRect( images[math.random(1,9)], cubeDimension, cubeDimension)

square1.x = cubeDimension * i

square1.y = screenH - halfCube - (cubeDimension*4) 

table.insert(myTable, square1)

end

-----------function to create new line of cubes  (it works, it’s just increasing memory probably because I’m not calling it in the right place)

function createCube1()

for i = 1, 7, 1 do

square1 = display.newImageRect( images[math.random(1,9)], cubeDimension, cubeDimension)

square1.x = cubeDimension * i

square1.y = screenH - halfCube - (cubeDimension*4) 

table.insert(myTable, square1)

end

end

–boolean to help with above function

createCube = false

-----the…LOOP

local function loop()

    for i = #myTable, 1, -1 do

        local object = myTable[i]

        

        if object ~= nil then

        object.y = object.y + 5

end

   

        if object.y > 834 then 

        myTable[i]:removeSelf()

table.remove(myTable,i)

object:removeSelf()

        end

    end

end

Runtime:addEventListener(“enterFrame”, loop)

Never mind, its pretty obvious, call the createcube () OUTSIDE the loop DUH! Been programming for more that 16 hours so I’m fried! Thanks again!

By the way, here are some extra pointers for removing your objects from the table:

  1. Do not nil the object if you’re using table.remove(), as table.remove() automatically deletes the object when finished. Setting it to nil will end up setting the object  after it to nil, because table.remove() takes the element out and “re-stacks” the table behind it.

Visual explanation (complete with beautiful hand-authored ASCII art :D):

[EDIT:] *Sigh*… It doesn’t look so good on the forum software :frowning:

[lua]

  •                                                                                               +

  •                              + + + + + + + + + + + + + +                                      +

  •                              + Say, perchance, that we +                                      +

  •                              + should remove t[i] now: +                                      +

  •                              + + + + + + +|+ + + + + + +                                      +

  • Iteration (i = x):                        V                                                   +

  • --------------------------------------------------------------------------------------------- +

  • Original  |  #t  |  #t - 1  |  #t - 2  |  table.remove(t[i])  |  t[i] = nil                   +

  • --------------------------------------------------------------------------------------------- +

  • A         |  A   |  A       |  A       |  A                   |  A                            +

  • B         |  B   |  B       |  B       |  B                   |  B                            +

  • C         |  C   |  C       |  C       |  C                   |  C                            +

  • D         |  D   |  D       |  D       |  D                   |  D                            +

  • E         |  E   |  E       | <E>      |  F <- E removed      |  [F] <- F is now nil, not E   +

  • F         |  F   |  <F>     |  F       |  G                   |  G                            +

  • G         | <G>  |  G       |  G       |                      |                               +

[/lua]

  1. As thomas6 said, don’t go crazy with the garbage collecting. Because of the way Lua works, you don’t ever need to call it manually, unless you need to gauge your memory or quickly compensate for a memory warning.

  2. You should use display.remove() over :removeSelf(), because display.remove() does nil checking, while :removeSelf() will throw an error if the object doesn’t exist (attempting to index local ‘obj’ (a nil value) )

[lua]

display.remove(object)

[/lua]

Also important: When deleting objects from an (indexed) table, you should use table.remove(), not t[i] = nil, because simply nil-ing out the object leads to problems with iteration. Using the length operator (#) on it ends up as the lowest non-nil value, so you end up with almost un-findable bugs.

Hope this helps :slight_smile:

  • Caleb