Dictionary Array Append Conundrum

Well, for me, anyway.

I have a WebPage with a propery defined as an array of Dictionaries (inQ).
In my code I have

Dim thisMsg As New Dictionary

which I use to build up my data. I then do this :

inQ.Append thisMsg

which adds the data just fine to the dictionary array. A breakpoint shows me that the data is correct.

However, I want to clear thisMsg each time I consider it complete for that dictionary’s data collection. When I do this immediately after the append :

thisMsg.Clear

then the InQ array, upon inspection during the same breakpoint, is empty. It has the right number of elements but they are all blank dictionary elements.

Clearing the “local” copy of the dictionary data that is added to the inQ array surely shouldn’t clear that data as well? They’re different, aren’t they?

Any pointers would be gratefully received.

No, they aren’t different. When you assign a Dictionary (or any other object) to another variable, or add it to an array, you are not making a copy of it, you are just assigning a reference to the same object.

After you assign it to the array, replace the local variable with a new Dictionary.

inQ.Append thisMsg
thisMsg = new Dictionary

It appears you are using the same reference (thisMsg) in both places so they would be the same actual dictionary object.

Ah, OK.
So any object assignment is just a pointer to that object rather than a copy.

Thanks both of you, but Kem was first so he gets the “Answered” badge :slight_smile:

*** EDIT
Actually, whilst I’m sure you’re right (and before a re-mark you as answered), what happens when the temporary variable goes out of scope? Does my array get blanked again?

FYI, technically a string is an object too so, for example, passing a single character to a method is no different than passing a 10 MB string. In either case, all that’s passed is a pointer to your string. It’s just that strings are immutable so it acts like you’re passing a copy.

My array is essentially a queue which will be traversed at a later stage and deleted element by element as it’s processed.

If my temporary dictionary variable goes out of scope I’m assuming it will be destroyed, thus taking out the array at the same time. Should I be creating a new array element and using the new element to build up the data, thus removing the need for the temporary variable? If so, I can’t seem to work out the syntax for doing that.

There’s a bit of this I’m not getting, sorry.

No. As long as there is a reference to the dictionary object, it will remain intact.

dim thisMsg as New Dictionary    // 1 reference
inQ.Append thisMsg  // now there are 2 references
thisMsg = nil  // or thisMsg goes out of scope, now there is 1 reference (in inQ).

Tim’s explanation is spot on. David, you might be over-thinking this. :slight_smile:

dim thisMsg as New Dictionary    // 1 reference
inQ.Append thisMsg  // now there are 2 references
thisMsg = New Dictionary  // now there are 2 dictionary objects, each with 1 reference
inQ.Append thisMsg
thisMsg = New Dictionary // now there are 3 dictionary objects, etc

@Kem - almost certainly :slight_smile: however I want to properly understand what I’m doing here, and I’m missing something.

Is thisMsg.Clear different to the variable going out of scope?
If the append is creating a reference to the data stored elsewhere then when does the data, originally create by thisMsg but then referenced by inQ(), get destroyed?

Or is this some kind of automatic garbage collection that will remove the data when the final reference to it is deleted? If so I assume I am relying on Xojo to clean up for me rather than being able to do it myself?

Apologies if this is Xojo 101, but i will get it eventually :slight_smile:

Ok, testing shows that using the method described by Tim above works fine. When the event handler finishes the inQ array (a property of the WebPage) retains its data.

So my thought now is if the array inQ is holding a pointer to the data, when does the data get destroyed? Is it automatic garbage collection when I one by one remove the array elements? I can see that the array gets destroyed, I just want to be sure that there’s not a memory leak going on here.

Thanks,

Clear is a method implemented within the Dictionary class, so calling that is still working within the same Dictionary object. This does not affect the references to that object.

Xojo uses internal reference counting so an object is finally removed when the references to it drop to zero. Appending an object to an array will create another reference to that object as will assigning it to the value of a Dictionary. So let’s take an example:

dim d as new Dictionary // One reference to a Dictionary object we'll call "d1"
dim arr() as Dictionary
arr.Append d // Now two references to d1
d = new Dictionary // The reference to d1 is removed and a new Dictionary created (d2)
arr.Append d // Now arr(0) holds d1 and is the only reference, and arr(1) points to d2 (two references)
d = nil // Now there is only one reference to d2
redim arr(-1) // All references to d1 and d2 are gone, so those Dictionary object are gone too
// If the values of d1 or d2 had exclusive references to any objects, they are gone now too

Basically the rule of thumb is, if you can access an object, then it exists and occupies memory. As soon as you no longer have a way to access it (its not assigned to any variable, property, array, or Dictionary), then the object is “gone” and the RAM it occupied is freed.

The only way you can create a memory leak is with a circular reference: Object1 stores Object2 which stores Object1. So don’t do that. :slight_smile:

Thanks for that, Kem.
The automatic destruction was the “magic” bit I was missing, and within that context the clear method behaviour makes perfect sense now. I’m just so used to killing everything myself I can’t get out of the mentality.

I’m going to mark Kem as the answerer, but you’re all winners in my eyes :slight_smile:

Thanks, all. I’m another step closer.