Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

  1. Home
  2. Pascal Dictionary
  3. Pointer Basics

Pointer Basics

Pascal pointers are variables that hold a memory address directly. A pointer type is declared by placing ^ before the type name; heap memory is allocated with New and the value at the pointed-to address is read or written using the ^ dereference operator. When the memory is no longer needed it is released with Dispose. Correct use of pointers makes it possible to build dynamic data structures such as linked lists and trees.

Syntax

{ -----------------------------------------------
  Declaring a pointer type
  ----------------------------------------------- }

type
  TypeNamePtr = ^TypeName;  { Defines a pointer type to an existing type }

var
  ptrVar : ^TypeName;  { Can also be declared directly without a named type }

{ -----------------------------------------------
  Allocating and releasing heap memory
  ----------------------------------------------- }

New(ptrVar);      { Allocates heap memory and stores the address in ptrVar }
Dispose(ptrVar);  { Releases the heap memory. Access after release is forbidden. }

{ -----------------------------------------------
  Dereferencing (^ operator)
  ----------------------------------------------- }

ptrVar^ := value;    { Writes a value to the address the pointer points to }
variable := ptrVar^; { Reads the value from the address the pointer points to }

{ -----------------------------------------------
  Address-of (@ operator)
  ----------------------------------------------- }

ptrVar := @existingVar;  { Stores the address of an existing variable in ptrVar }

{ -----------------------------------------------
  nil (null pointer)
  ----------------------------------------------- }

ptrVar := nil;           { A safe initial value meaning "points to nothing" }
if ptrVar = nil then ... { Verify before access with a nil check }

Syntax Reference

Syntax / OperatorDescription
^TypeName (in type declaration)Declares a pointer type to the specified type. Often given a name in a TYPE declaration, e.g. type PIntPtr = ^Integer;.
ptrVar^ (dereference)Accesses the actual value at the address the pointer holds. Used for both reading and writing.
@variableObtains the memory address of a variable. Used when you want to manipulate an existing variable through a pointer.
New(p)Allocates heap memory sized to the type of p^ and stores the address in p.
Dispose(p)Releases heap memory allocated with New. Passing nil causes a runtime error.
nilA pointer value meaning "points to nothing." Assigning it in place of an uninitialised pointer is safer.
Assigned(p)Returns True if p is not nil. Equivalent to p <> nil but easier to read.

Sample Code

db_pointer.pas
{ db_pointer.pas — Sample demonstrating Pascal pointer basics }
{ Uses Dragon Ball character data to show }
{ pointer type declaration, New / Dispose, and dereferencing }
{
  Compile and run:
    fpc db_pointer.pas && ./db_pointer
}

program db_pointer;

{ -----------------------------------------------
  Define a record type and its corresponding pointer type
  ----------------------------------------------- }
type
  TFighter = record
    name       : string[20];  { Character name }
    power_level: LongInt;     { Power level }
  end;
  PFighter = ^TFighter;       { Pointer type for TFighter }

var
  { -----------------------------------------------
    Pointer variable declarations
    ----------------------------------------------- }
  p1 : PFighter;   { Pointer to heap-allocated fighter data }
  p2 : PFighter;   { Pointer to another fighter record }
  p3 : PFighter;   { Pointer to a stack variable (used with @) }

  { A regular record variable on the stack }
  local_fighter : TFighter;

  { Variables for the integer pointer example }
  pi     : ^LongInt;
  score  : LongInt;

begin
  WriteLn('===== Dragon Ball Pointer Sample =====');
  WriteLn('');

  { -----------------------------------------------
    1. Allocate heap memory with New and write values
    ----------------------------------------------- }
  New(p1);                         { Allocates TFighter-sized heap memory }
  p1^.name        := 'Son Goku';   { Dereference and write to the field }
  p1^.power_level := 9000;

  New(p2);
  p2^.name        := 'Vegeta';
  p2^.power_level := 8500;

  WriteLn('--- Fighter data allocated with New ---');
  WriteLn('  p1^ : ', p1^.name, '  Power level = ', p1^.power_level);
  WriteLn('  p2^ : ', p2^.name, '  Power level = ', p2^.power_level);
  WriteLn('');

  { -----------------------------------------------
    2. Update a value through dereferencing
    ----------------------------------------------- }
  p1^.power_level := 150000000;   { Super Saiyan awakening; update power level }
  WriteLn('--- After updating power level ---');
  WriteLn('  p1^ : ', p1^.name, '  Power level = ', p1^.power_level);
  WriteLn('');

  { -----------------------------------------------
    3. Get the address of a stack variable with @
    ----------------------------------------------- }
  local_fighter.name        := 'Piccolo';
  local_fighter.power_level := 3500;

  p3 := @local_fighter;            { Store local_fighter's address in p3 }
  WriteLn('--- Pointing to a stack variable with @ ---');
  WriteLn('  p3^ : ', p3^.name, '  Power level = ', p3^.power_level);

  { The value of local_fighter can be changed through p3 }
  p3^.power_level := 8000;
  WriteLn('  After update via p3: local_fighter.power_level = ', local_fighter.power_level);
  WriteLn('');

  { -----------------------------------------------
    4. Basic operations with an integer pointer
    ----------------------------------------------- }
  New(pi);
  pi^ := 999999;     { Write a value to the address the pointer points to }
  score := pi^;      { Read the value from the pointer into a variable }
  WriteLn('--- Integer pointer ---');
  WriteLn('  pi^ = ', pi^, '  score = ', score);
  Dispose(pi);       { Release heap memory that is no longer needed }
  WriteLn('  pi has been Disposed.');
  WriteLn('');

  { -----------------------------------------------
    5. nil check and the Assigned function
    ----------------------------------------------- }
  p3 := nil;   { p3 was pointing to a stack variable; reset it to nil }
  WriteLn('--- nil / Assigned check ---');
  if not Assigned(p1) then
    WriteLn('  p1 is nil.')
  else
    WriteLn('  p1 points to a valid address. (Assigned = True)');

  if p3 = nil then
    WriteLn('  p3 is nil.');
  WriteLn('');

  { -----------------------------------------------
    6. Release heap memory
    ----------------------------------------------- }
  Dispose(p1);
  Dispose(p2);
  WriteLn('--- p1 and p2 have been Disposed. ---');
  WriteLn('==========================================');
end.
fpc db_pointer.pas && ./db_pointer
Free Pascal Compiler version ...
Linking ./db_pointer
===== Dragon Ball Pointer Sample =====

--- Fighter data allocated with New ---
  p1^ : Son Goku  Power level = 9000
  p2^ : Vegeta  Power level = 8500

--- After updating power level ---
  p1^ : Son Goku  Power level = 150000000

--- Pointing to a stack variable with @ ---
  p3^ : Piccolo  Power level = 3500
  After update via p3: local_fighter.power_level = 8000

--- Integer pointer ---
  pi^ = 999999  score = 999999
  pi has been Disposed.

--- nil / Assigned check ---
  p1 points to a valid address. (Assigned = True)
  p3 is nil.

--- p1 and p2 have been Disposed. ---
==========================================

Common Mistakes

Dereferencing an uninitialised pointer

A pointer variable immediately after declaration does not hold nil; it holds an undefined value. Dereferencing (p^) before allocating memory with New or GetMem accesses an invalid address.

Not setting a pointer to nil after Dispose

A pointer that has been released with Dispose becomes a dangling pointer if accessed again. Assigning p := nil immediately after Dispose helps prevent accidental reuse through nil checks.

Confusion over the position of ^ compared with C

In Pascal, a pointer type in a type declaration is written as PMyType = ^MyType (^ before the type), while dereferencing is written as p^ (^ after the variable). Mixing this up with C's *p and writing p* causes a compile error.

Overview

Pascal pointers are type-safe: declaring them as ^TypeName lets the compiler detect unintended type mismatches at compile time. Heap memory is allocated with New and released with Dispose. Assigning nil to a pointer variable after release helps prevent double-free and dangling pointer bugs. Combined with record types, pointers make it possible to implement dynamic data structures such as linked lists and trees — that application is covered on a separate page. For records, which are often used as the pointed-to type, see Record Types (record). For another approach to dynamic arrays see Dynamic Arrays (GetMem / SetLength).

If you find any errors or copyright issues, please .