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.