GET_MEMORY
. In C it is called malloc
. In the
textbook it is called new
.
GET_MEMORY
is called it returns an address
and the user needs to be able to store that address in a variable in
order to make use of it later on.
In our example, each student entry contains the address of the next student entry; e.g. JOE's entry contains the address of MARYJANE's entry. Therefore, a student entry must be a structure/record whose first component is capable of storing an address. Variables that hold addresses are called pointers.
In C, to declare a variable that can hold a real
value, you say:
float X ; (in the textbook: var X: real)To declare a variable that can hold the address of a real value, say:
float *P ; (in the textbook: var P: PointerTo real)
P = NULL;
means that P
is defined, but
contains no address. We can test this: if (P == NULL) ...
Typically, we use NULL
to indicate either then end of a
chain of links or an uninitialized address.
We require a procedure for returning/freeing one block of memory. The user will pass to this procedure a pointer (variable containing an address) and the procedure will return the corresponding block of memory to the global pool.
This procedure works on one block at a time. To free up all the space consumed by the student entries for one course, the user would have to call the procedure once for each student entry. Calling it just on the entry for JOE would not also free up the following entries. The entry for MARYJANE would still occupy memory.
Before freeing JOE:
After freeing JOE:Unfortunately, now we'd have no way to free MARYJANE because we forgot to retrieve its address from JOE's entry before we freed it. This is a very common mistake! Look out for it in your own code.
The procedure for returning memory to the global pool has different
names in different systems, I will call it by the generic name
RETURN_MEMORY
. In C it is called free
. In
the textbook it is called dispose
.
We require methods for accessing, i.e. looking at and changing, the value (or more generally, the object) stored at a particular address. This is done by dereferencing a pointer, or rather its value.
For example, in C, if P
is a pointer and contains a
valid address (i.e. not NULL), we can obtain the value stored at this
address by means of the *
prefix operator.
X = *P;
P
is pointing at and stores it
in X
.
*P = 13.1;
P
points at
(assuming P
is of type real*
, that is
`pointer to real').
X, an ordinary variable, is memory cell 7. It contains a real value, 3.9. P, a pointer variable, is memory cell 2. It contains an address, 5. (*P) is the memory cell whose address is stored in P, i.e. memory cell 5. It contains a real value, 4.8.
*P = X;
Note that P itself has not changed.
The textbook uses a different symbol for the dereferencing operator. The symbol is ^ and it is placed after the pointer variable, not before it. So the textbook writes (P^) instead of (*P).
Finally, it is sometimes useful to have a procedure that takes a symbolic variable name, like X, and returns the address corresponding to the name. In the above example, X is a symbolic name for the address 7. In C, this operation is done using the symbol & - (&X) is the address corresponding to X. The text has no notation for this.