Diagnosing Access Violations in Delphi Applications
Step‑by‑step diagnostic guide for fixing Access Violations in Delphi apps, covering dangling pointers, nil calls, interface cycles, and VCL ownership.
18 Jul 2026, 17:05 UTC

Recognizable Condition
An Access Violation (AV) appears at runtime with a message like "Access violation at address 0x00401234 in module 'MyApp.exe'. Read of address 0x00000008." The address often points to memory that has been freed or never allocated.
Common Causes and Diagnostic Indicators
| Cause | Typical Symptom | Quick Check |
|---|---|---|
| Dangling pointer after manual .Free | AV occurs when a variable that held the object is later used. | Search for .Free or Dispose on the class; verify no other variable still references it. |
| Nil pointer method call | AV with address 0x00000000 or low value. | Inspect the variable before the call; ensure it was instantiated via Create. |
| Interface reference‑counting cycle | Object destroyed unexpectedly while an interface variable still holds it. | Look for circular interface references; check if any interface uses [weak] attribute. |
| VCL double‑free via ownership chain | Component freed manually then later freed by its parent (form). | Identify if the component has an Owner (usually the form) and whether you called Free on it. |
Ordered Checks
- Enable full debug symbols and reproduce the AV. Note the exact address and module.
- Open the CPU view in the debugger; locate the instruction that caused the fault.
- Check the registers (EAX, EBX, etc.) to see if they contain a pointer value; compare with known object addresses.
- If the address is near zero, suspect a nil pointer; trace back to the variable used in the call.
- If the address points to a valid memory region that was recently freed, look for a .Free or Dispose on the class.
- Inspect any interface variables that reference the object; verify reference counting and absence of cycles.
- For VCL components, check the Owner property; if Owner is assigned, avoid manual Free.
Fixes Tied to Findings
- Dangling pointer: Replace manual .Free with
FreeAndNil(MyObj);or set the variable to nil after Free. - Nil pointer: Ensure the object is created before use:
if MyObj = nil then MyObj := TMyClass.Create; - Interface cycle: Break the cycle by declaring one interface reference as
[weak]or usingTInterfacedObjectwith explicit _Release. - VCL double‑free: Remove the manual Free; let the Owner destroy the component, or set
MyComponent.Parent := nil;before Free if needed. - Enable FastMM4 in debug mode (
Define FastMM4in project options) to catch illegal accesses immediately. - Use the Windows Event Viewer or Delphi’s Exception Log to capture the call stack.
- Consider whether third‑party DLLs or packages are involved; isolate them by disabling packages one‑by‑one.
- If the fault address changes each run, suspect stack corruption; review local variable usage and large stack allocations.
- Reproduce the scenario that previously triggered the AV.
- Confirm that no exception is raised.
- Open the FastMM4 leak report (if enabled) to ensure no new leaks were introduced.
- Optionally, set a breakpoint on the former fault address; the debugger should never hit it.
Escalation Criteria
If the AV persists after applying the above checks:
Practical Verification
After applying a fix, run the application under the debugger:
Limitations
This guide addresses AVs originating from Delphi‑managed memory. Issues caused by hardware faults, operating‑system memory protection, or bugs in external libraries may require additional tools such as VMMap or hardware diagnostics.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.