delphi - TryGetvalue doesn't work if individual items are freed - memory leaks if they aren't -


i discovered win32 compile of fmx application has bug!

the problem trygetvalue returns unknown mypoi's if {$define free_mypoi}. if don't define (ie. not free each instance of mypoi after added dictionary), eurekalog reports memory leaks when app exits (my poi hasn't been freed obviously).

most interesting, problem doesn't occur in android version of code free_mypoi defined. (thankfully)

is way of adding items dictionary correct? (for android , win32 fmx)

here core code:

type   tmypoi = class(tobject)   public     value: integer;     timestamp: tdatetime;   end;  ...  function tform2.createorupdate(username: string; newtimestamp: tdatetime): string; var   poitimestamp: tdatetime;   mypoi: tmypoi;   index: integer; begin    if poidict.trygetvalue(username, mypoi)   begin     // existing poi     result := inttostr(mypoi.value) + ' ' + datetimetostr(mypoi.timestamp);     poitimestamp := mypoi.timestamp;     // update poi's timestamp     mypoi.timestamp := newtimestamp;     poidict.addorsetvalue(username, mypoi);   end   else   begin     // add new poi     index := random(999);     result := inttostr(index) + ' ' + datetimetostr(newtimestamp);     mypoi := tmypoi.create; {$ifdef free_mypoi}     try {$endif}       mypoi.value := index;       mypoi.timestamp := newtimestamp;       poidict.add(username, mypoi); {$ifdef free_mypoi}           mypoi.free;     end; {$endif}   end;  end;  initialization   poidict := tdictionary<string, tmypoi>.create;  finalization   poidict.free;  end. 

addendum: not arc-specific question. question managing object references.

first, don't ever free object created , added kind of collection. should transfer ownership on object collection. following code inherently broken on windows - because creating dangling references inside dictionary - blow on sooner or later.

    mypoi := tmypoi.create; {$ifdef free_mypoi}     try {$endif}       mypoi.value := index;       mypoi.timestamp := newtimestamp;       poidict.add(username, mypoi); {$ifdef free_mypoi}           mypoi.free;     end; {$endif} 

you should use tobjectdictionary takes ownership on values. work without leaks on platforms.

 poidict := tobjectdictionary<string, tmypoi>.create([doownsvalues]); 

next thing, mypoi object, don't have add again changed timestamp, can change timestamp directly - poidict.trygetvalue(username, mypoi) give reference not create copy of object.

corrected code like:

function tform2.createorupdate(username: string; newtimestamp: tdatetime): string; var   poitimestamp: tdatetime;   mypoi: tmypoi;   index: integer; begin    if poidict.trygetvalue(username, mypoi)   begin     // existing poi     result := inttostr(mypoi.value) + ' ' + datetimetostr(mypoi.timestamp);     poitimestamp := mypoi.timestamp;     // update poi's timestamp - update object in dictionary      mypoi.timestamp := newtimestamp;   end   else   begin     // add new poi     index := random(999);     result := inttostr(index) + ' ' + datetimetostr(newtimestamp);     mypoi := tmypoi.create;     try       mypoi.value := index;       mypoi.timestamp := newtimestamp;       poidict.add(username, mypoi);     except       mypoi.free;       raise;     end;   end;  end;  initialization   poidict := tobjectdictionary<string, tmypoi>.create([doownsvalues]);  finalization   poidict.free;  end. 

Comments

Popular posts from this blog

ubuntu - PHP script to find files of certain extensions in a directory, returns populated array when run in browser, but empty array when run from terminal -

php - How can i create a user dashboard -

javascript - How to detect toggling of the fullscreen-toolbar in jQuery Mobile? -