// *** before: ***
// assigning a record copied its bytes. If the record owned a pointer or
// an object, both copies now pointed at the same thing, and the second
// destructor freed it twice
type
TBuffer = record
Data: Pointer;
Size: Integer;
end;
var
A, B: TBuffer;
begin
B := A; // one buffer, two owners
end;
// *** in version 10.4: ***
type
TBuffer = record
public
Data: Pointer;
Size: Integer;
class operator Initialize(out Dest: TBuffer);
class operator Finalize(var Dest: TBuffer);
class operator Assign(var Dest: TBuffer; const [ref] Src: TBuffer);
end;
class operator TBuffer.Assign(var Dest: TBuffer; const [ref] Src: TBuffer);
begin
FreeMem(Dest.Data);
Dest.Size := Src.Size;
GetMem(Dest.Data, Dest.Size);
Move(Src.Data^, Dest.Data^, Dest.Size); // a copy of its own
end;
var
A, B: TBuffer;
begin
B := A; // the operator runs, and each side owns its own
end;