Memory Management and Object Ownership
21.1 Memory Management Models
Ordinals, floats, records without managed fields, static arrays Value types (stack/inline)
string, dynamic arrays, Variant, interfaces, anonymous methods Automatic reference counting Class instances (TObject descendants)
Manual (Free), or via an owner, or interface refcounting Custom managed records (10.4+)
Custom Initialize/Finalize/Assign operators
21.2 Ownership Patterns
// 1. try..finally (local objects)
var Obj := TFoo.Create;
try ... finally Obj.Free; end;
// 2. Component ownership: the owner frees the component automatically
var Btn := TButton.Create(Self); // Self (the form) owns the button
Btn.Parent := Self; // Parent = visual container (different from the owner!)
// 3. Object lists that own their items
var List := TObjectList<TCustomer>.Create(True); // OwnsObjects = True
try
List.Add(TCustomer.Create('Ana'));
finally
List.Free; // frees all customers too
end;
// 4. Interfaces (automatic)
var Svc: IService := TService.Create;
// 5. Smart pointer pattern (custom managed record or Spring4D Shared<T>)21.3 Detecting Leaks
Tools: FastMM4/FastMM5 full debug mode (stack traces for leaks, use-after-free detection), madExcept, EurekaLog, DeLeaker, AQTime (historical).
begin
ReportMemoryLeaksOnShutdown := True; // in the .dpr (Debug builds)
...
end.21.4 Common Memory Bugs
Forgetting Free (leak), double free / freeing an object still in use (access violation), using an object after Free (dangling reference: use FreeAndNil), mixing object and interface references, circular interface references, not calling inherited Destroy, freeing a component with an owner without removing it first (it's fine to Free, since the component notifies its owner), and string/array pointer misuse after reallocation.