DMarlon Studio

Lesson 9 · 9 of 20

Pointers, New and Dispose · Pascal

Work with pointers in Pascal: addresses with @, access with ^, and dynamic memory allocated with New and released with Dispose.

Pascal · Pointers, New and Dispose in DMarlon Studio: the example's code and its output in the terminal

A pointer holds the address of a value, not the value. PProduct = ^TProduct declares a pointer to TProduct, and PInteger comes predefined in the RTL. By convention, pointer types start with P.

`@units` takes the address of a variable that already exists, and `pUnits^` follows the pointer to the value. So pUnits^ := pUnits^ + 5 changes units itself, which goes from 10 to 15. The output never shows addresses: they change on every run and say nothing useful.

`New(item)` allocates a fresh TProduct on the heap and leaves its address in item; it also initialises managed fields such as Name. From then on you work with item^.Name and item^.Stock. Restock receives the pointer and modifies the original record, not a copy.

`Dispose(item)` gives that memory back. What you allocate with New you release with Dispose, exactly once; forget it and you have a leak. Afterwards, set the pointer to `nil` so a released address is never used by mistake, and `Assigned` tells you whether it points at anything.

The objects from earlier lessons are pointers underneath: Create and Free play the part of New and Dispose. Knowing how this works explains why assigning an object only copies the reference.

Code · main.pas

program main;type  TProduct = record    Name: String;    Stock: Integer;  end;  PProduct = ^TProduct;  // a pointer to a TProductprocedure Restock(item: PProduct; amount: Integer);begin  Inc(item^.Stock, amount);  // changes the record it points toend;var  units: Integer;  pUnits: PInteger;  item: PProduct;begin  units := 10;  pUnits := @units;           // the address of an existing variable  pUnits^ := pUnits^ + 5;     // ^ follows the pointer  WriteLn('units = ', units);  item := nil;  WriteLn('Assigned before New: ', Assigned(item));  New(item);                  // a new record on the heap  item^.Name := 'Printer toner';  item^.Stock := 3;  Restock(item, 12);  WriteLn(item^.Name, ': ', item^.Stock, ' in stock');  Dispose(item);              // give the memory back  item := nil;                // and forget the old address  WriteLn('Assigned after Dispose: ', Assigned(item));end.

Output · fpc main.pas && ./main

units = 15
Assigned before New: FALSE
Printer toner: 15 in stock
Assigned after Dispose: FALSE

Key points

  • @x is the address of x; p^ is the value p points to.
  • New allocates on the heap; Dispose releases it.
  • Every New needs exactly one Dispose.
  • After Dispose, set the pointer to nil.
  • Assigned(p) tells you whether p points at something.

Exercise

Allocate a second product with New, 'Paper A4' with 40 units, print the combined stock of both and release them with Dispose.