Repository navigation
global set in initialization never freed
Alexander Liberov edited this page Nov 8, 2026
·
1 revision
A unit's initialization sets its own global variable to a new object (G:= TFoo.Create), and no source that names the variable frees it. The object lives to process exit and shows in every leak report, which hides the leaks that matter. ON by default in lint-all and lint-project.
drag-lint lint-all --db <project.sqlite> --rule global-set-in-initialization-never-freed
drag-lint lint-project --db <project.sqlite> --rule global-set-in-initialization-never-freed
It needs an index that has resolved references to sections (1.44 or later).
One hint per variable, at the assignment. The assignment is in the section, or in a routine of the same unit that the section calls.
- Any unit that names the variable and frees it:
G.Free,G.Destroy,G.DisposeOf,G.Release,FreeAndNil(G)or anyFree...(G). The check is on the text, so a free in a comment also silences it. -
G.FreeOnTerminate, and a variable handed toAdd,AddObject,Insert,Push,Enqueueor aRegister...call: something else owns it. - A constructor with an owner argument: a first argument that is an identifier other than
nil,TrueorFalse. - An interface-typed variable, and a type not proven to be a class: a record has a
Createtoo, such asTRegEx. The project index and the platform library answer; with no library loaded only project classes and a short list of common RTL classes count. - A factory call: only
.Createproves a new object. - A variable of another unit.