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
Post a Comment