Watch, Follow, &
Connect with Us
Public Report
Report From: Delphi-BCB/RTL/Delphi/Other Classes    [ Add a report in this area ]  
Report #:  75851   Status: Closed
TObjectDictionary.Remove frees wrong values
Project:  Delphi Build #:  12.0.3420.21218
Version:    12.1 Submitted By:   David Muller
Report Type:  Basic functionality failure Date Reported:  7/16/2009 8:14:18 AM
Severity:    Serious / Highly visible problem Last Updated: 3/20/2012 2:24:39 AM
Platform:    All platforms Internal Tracking #:   269410
Resolution: Fixed (Resolution Comments) Resolved in Build: : Delphi 2010
Duplicate of:  None
Voting and Rating
Overall Rating: No Ratings Yet
0.00 out of 5
Total Votes: 6
Description
Calling TObjectDictionary.Remove when the dictionary owns values may result in the wrong value being freed.
Steps to Reproduce:
ype
  TObj = Class
  Private
    fName: String;
  Public
    Constructor Create(const aName: String);
    Destructor Destroy; override;
  End;

{ TObj }

constructor TObj.Create(const aName: String);
begin
  fName := aName;
end;

destructor TObj.Destroy;
begin
  Form1.Memo1.Lines.Add(fName + ' being destroyed');
  inherited;
end;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
Var
  Dict: TObjectDictionary<String, TObj>;
begin
  Dict := TObjectDictionary<String, TObj>.Create([doOwnsValues]);
  Dict.Add('Part1', TObj.Create('Part1'));
  Dict.Add('Part2', TObj.Create('Part2'));
  Dict.Add('Part3', TObj.Create('Part3'));
  Dict.Add('Part4', TObj.Create('Part4'));
  Dict.Remove('Part1');
  Memo1.Lines.Add('----');
  Dict.Free;
end;

Expected Output:
Part1 being destroyed
----
.
.
.

Actual Output:
Part3 being destroyed
-----
.
.
.

+ Exception thrown when the dictionary tries to double free Part3.
Workarounds
Use a StringList instead - but no automatic lifetime management & lots of casting required.
Attachment
None
Comments

None

Server Response from: ETNACODE01