Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Pointers

A pointer holds the address of a value. Through it you can read and write the value from somewhere that does not know its name, which is how heap memory is reached and how linked structures are built.

'' An address, and what lives at it.
dim as int32 n = 10
dim as int32 ptr p = @n                 '' @ takes the address
print "*p ="; *p                        '' * reads what p points at
*p = 20                                 '' ...or writes it
print "n is now"; n

type Point
    as int32 x, y
end type

dim as Point pt = ( 3, 4 )
dim as Point ptr pp = @pt
pp->x = 30                              '' -> reaches a field
print "pt is"; pt.x; pt.y

'' Arithmetic counts elements, not bytes.
dim as int32 a( 0 to 4 ) = { 10, 20, 30, 40, 50 }
dim as int32 ptr first = @a( 0 )
print "first[2] ="; first[2]; ", *( first + 3 ) ="; *( first + 3 )

dim as uint8 ptr bytes = cast( uint8 ptr, first )
print "int32 ptr + 1 moves"; cast( integer, first + 1 ) - cast( integer, first )
print "uint8 ptr + 1 moves"; cast( integer, bytes + 1 ) - cast( integer, bytes )

'' Walking a run of elements, and the distance between two pointers.
dim as int32 ptr lastOne = @a( 4 ), q = first
print "walked:";
do while q <= lastOne
    print *q;
    q += 1
loop
print
print "lastOne - first ="; lastOne - first

Output

*p = 10
n is now 20
pt is 30 4
first[2] = 30, *( first + 3 ) = 40
int32 ptr + 1 moves 4
uint8 ptr + 1 moves 1
walked: 10 20 30 40 50
lastOne - first = 4
WrittenMeans
int32 ptrthe type: an address of an int32
@nthe address of n
*pthe value at p, for reading or writing
p->xfield x of the record at p; the same as ( *p ).x
p[i]the element i places after p; the same as *( p + i )

Writing through *p changed n, because p holds n's address: there is one value and two ways to reach it.

Pointer arithmetic counts elements, not bytes. first + 1 is the next int32, four bytes on; the same step on a uint8 ptr is one byte. That is why a pointer to an array's first element can be indexed like the array, and why subtracting two pointers into one array gives the number of elements between them, 4 here.

Pitfall

@v + 3, with v an int32, is not three bytes past v: it is three int32s, twelve bytes, outside v altogether. Reading there returns whatever is next in memory and nothing reports it. To step in bytes, step through a byte pointer: cast( uint8 ptr, @v ) + 3.

cast( uint8 ptr, first ) reinterprets an address as a pointer to another type. any ptr is an address with no type at all: every pointer converts to it and back without a cast, and it cannot be dereferenced until you convert it to a typed pointer.

Activities

  1. Print the bytes of the int32 value 258 through a uint8 ptr. Which byte comes first?
  2. Walk a backwards with a pointer, from lastOne down to first.