ParamArray causes memory leak

Consider following two methods:

    sub method_a(a as class1)
    end sub

    sub method_b(paramarray a as class1)
    end sub

When calling method_a, the object destructs immediately after the call (as expected).

When calling method_b, the object survives until the end of the method, even though nothing refers to it.

    method_a new class1
    //class1 destructs here, before following break statement is hit
    break
    method_b new class1
    //class1 DOES NOT destruct here. It survives after following break statement, until the very end of the method
    break

[quote=464735:@Thomas Sanham]method_b new class1
//class1 DOES NOT destruct here. It survives after following break statement, until the very end of the method
break[/quote]

maybe the scope is more like this, valid inside in method Test, but then i would also expect the same behavior.
it would be a memory leak if obj is valid/exists outside of the method test and garbage collector had run.

method Test() var obj = new class1 call method_b obj end method

Xojo does not have a garbage collector (mark space for future release from a background sweeping process), it uses reference count and releases objects immediately.

So it probably means that case a got 0 after return, and case b not. Not sure, but it appears a bug (potential leak) due to apparent inconsistency. Maybe a loop of cases b will cause a memory overflow due to not releasing it. It deserves a feedback case in case of such thing occurring.

somehow the same meaning reference count or garbage collector.

i meant it can be correct.

This conversation does not have to be in the Pre-Release channel as 2019r.1.1 does the same thing. I suspect it’s worked that way for quite some time and nobody noticed.

It seems like the code is doing something like this for you behind the scenes:

dim arr() as Class1 = array( new Class1 )
Method_B arr

That hidden (for lack of a better description) arr variable is treated like a local variable, so it survives until the end of the block, not the method per se. For example, this will cause immediate destruction:

if true then
  Method_B new Class1
end if // boom

Since Destruction occurs eventually, I’m not sure how this is a “leak”…

I think method_a causes correctly:

main:
Begin

   Begin // scope

      Var temp1 = New Class1
      call method_a temp1

   End // scope

End

And method_b wrongly:

main:
Begin

   // Begin // missing implicit scope

      Var temp1 = New Class1
      call method_a temp1

   // End // missing implicit scope

End

If the created In-Parameter value survives beyond the expected point of release, if it’s not a leak, at least is a bug, because the destructor code of the parameter object must run BEFORE the next line, as the implicit scope of such method ended.

I agree that it seems like a bug.

It deserves a review by the engineers.
So, please open a feedback, and with the arguments there, put a link to this conversation.

its like
scope/scope
…something
endscope/endscope

or
scope
…something
endscope

if it do something behind the scenes (because a paramarray) this scope in scope is not necessary.

If the implict scope is right, the release routine of a paramArray have some bug. Technically is a leak, because it escapes its scope.

I agree.

‘Leak’ might not have been the most helpful term for me to use, because the main problem is not to do with memory per se.

The problem becomes harmful when the object refers to an external resource.

To illustrate, imagine the following contrived pseudo-code example:

dim c as new opengl_context(...)
dim t as new texture
c.bind t
c.draw(...)
t=nil //fire t's destructor which calls glDeleteTexture in context of c
c=nil //fire destructor which cleans up context

Above code should work correctly, but crashes if ‘bind’ takes a paramarray, because ‘t’ outlives c and glDeleteTexture is called after the context has been destroyed.

A ‘Leak’ is something escaping its release and destruction scope and “floating around” unexpectedly. I agree it’s not a memory leak, but it’s a leak. A resource leak. There are more leaks than memory leaks, like handle, objects and resources leaks (most “non-memory” leak (low-level) can be generically said as a resource leak).

Workaround: surround the function that uses ParamArray with If True ... End If.

Also put it in the manual and be ashamed.

I use forced fake scope levels like that for a bunch of things
Usually in unit tests so I can keep variable names & such the same and then reuse them when I create a new test

Me, you, Kem, etc. People reading this today also. But anyone starting tomorrow or never reading this conversation just expect things working, no leaks, events working in the expected sequence, etc. And after suffering “weird” unexpected things and finding this symptom and conversation, the only vendor excuse is pointing in the “known problems” footnote of the ParamArray page a workaround listed there while not fixing it.

People here acquired the weird culture of “if a workaround exists for us, let’s just keep the bug there”. It gets on my nerves, and I always fight against this culture… a bit, before giving up.

I still wish that the OP post a feedback, unless he express he doesn’t want to.

<https://xojo.com/issue/58427>

@Thomas Sanham , they closed one duplicate and set a countdown to close the case without testing because they want you testing it deeper for them. Have a look in the <https://xojo.com/issue/58443> and say anything there.

Thanks. Example project has now been attached.