Jump to content
John Kouraklis

Why is TList freed in this code?

Recommended Posts

Hi,

I've got difficulties figuring out what is wrong with the following code:


program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  System.Generics.Collections;

var
  dic: TObjectDictionary<string, TList<string>>;
  list: TList<string>;
begin
  try
    dic:=TObjectDictionary<string, TList<string>>.Create([doOwnsValues]);
    list:=TList<string>.Create;
    list.Add('111');
    dic.AddOrSetValue('aaa', list);
    var gg: integer:=dic.Items['aaa'].Count;
    writeln(gg); // 1

    var l2: TList<string>:=dic.Items['aaa'];
    var a:integer:=l2.Count;
    writeln(a);        // 1

    l2.Add('222');
    a:=l2.Count;
    writeln(a);  // 2

    dic.Items['aaa']:=l2;

    a:=l2.Count;
    writeln(a);  // 0???

    a:=dic.Items['aaa'].count;
    writeln(a);  // 0???

    dic.Free;   // Invalid point?

    readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

When I assign the TList to the dictionary Value, it loses all the elements.

 

What am I doing wrong here? Can't see what is going on.

 

Thanks

Share this post


Link to post

The dic[‘aaa’] and l2 are the same object already. Hence, the assignment is not needed at all.

 

But the direct assignment (formerly known as “AddOrSetValue” in this case will set the value. This is done by removing (and destroying) the old value and after that add the new one... Thus the l2 is “cleared” (destroyed).

Share this post


Link to post
 dic.Items['aaa']:=l2;

dic.Items['aaa'] already contains l2 and l2 is freed before it is readded, since you set 

doOwnsValues

Also an issue would occur if you do

dic.Items['bbb']:=l2;

 

When the dictionary is destroyed the list will be freed twice.

Edited by pyscripter

Share this post


Link to post

So, the doOwnsValues frees the objects in assignments as well. I thought it only takes care of them when the dictionary is freed.

 

Thanks a lot guys

Share this post


Link to post

Also the owned objects are destroyed when items are removed from the dictionary. This is the same ownership model as the classic TObjectList. 

  • Like 1

Share this post


Link to post
16 minutes ago, Stefan Glienke said:

That's why IMultiMap<TKey,TValue> from Spring4d is so cool :classic_cool:

Only cool for the users. Mind-bending if it's your job to implement it!

  • Like 1
  • Haha 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×