Subject: Beginners' pointers 74. ***** Q: What are and how do I use pointers? A: This is a beginner's simplified introduction. A pointer is a variable type used to hold the address of another variable, that is to point to it. Pointers are used to 1) To refer to and manipulate variables indirectly. 2) In Turbo Pascal to obtain access to the heap storage area, which is not restricted to 64Kbytes. Consider the following example {$M 16384,0,80000} var yPtr : ^real; begin New(yPtr); yPtr^ := 3.14159; writeln ('2 times pi = ', 2.0 * yPtr^); Dispose(yPtr); yPtr := nil; end. Before we can discuss pointers we have to consider some rudiments of what a kind of a memory model a compiled Turbo Pascal program uses. This is a highly simplified presentation. For a more detailed presentation of the TP memory model see for example Tischer (1990b). +-------------------------+ | Heap | |-------------------------| | Data Segment | |-------------------------| | Code | |-------------------------| | Program Segment Prefix | +-------------------------+ When you write and compile a Turbo Pascal program it usually consists of (this is a simplification!) of the three lowest parts. When you define a global variable, it goes to the Data Segment. For example defining at the beginning of your program var x : real; requires 6 bytes from the data segment. (Local variables are placed on the stack.) Now, the catch is that because of the underlying 16-bit nature of MS-DOS, the size of the data segment cannot exceed 64Kb. On occasion the 64Kb is insufficient. However, if you use pointers, the corresponding variable values are held on the heap instead of the data segment or the stack. Before you can use the heap, you have to reserve it for your program. The following compiler directive makes a heap of 80000 bytes available to your program {$M 16384,0,80000}. (The syntax is {$M Stack size, Low heap limit, High heap limit}). With pointers you do not refer to a variable directly, but you point to it. For example, define var yPtr : ^real; Before you can use this pointer, you have to create this new dynamic variable as follows: New(yPtr); The New(yPtr) statement "Creates a new dynamic variable and sets a pointer variable to point to it." This pointer, yPtr, will point to the actual value, which the program puts on the heap. In your program you can write, for example yPtr^ := 3.14159; Think about the difference between yPtr and yPtr^. The former contains the value of the memory address where you now have put the value 3.14159. The latter gives that value. Hence yPtr^ can be used like any ordinary real variable. The difference is that it is on the heap, not on the data segment (or stack). Thus you can now use this pointer. For example you n write writeln ('2 times pi = ', 2.0 * yPtr^); When you do not need the pointer any more in your program you can dispose of it to release the memory allocated for other purposes: Dispose(yPtr); yPtr := nil; "After a call to Dispose, the value of yPtr is undefined and it is an error to reference yPtr. The reserved word nil denotes a pointer type constant that does not point to anything." Setting yPtr := nil is just good programming practice, because then you can later easily test whether the pointer is available or not. Disposing of a pointer within your program is not necessary unless the amount of memory is a critical consideration in your program. The heap will be released when your program terminates. To recount. What yPtr actually contains is the memory address of the value on the heap. When you write yPtr^, the caret indicates that you do not mean the pointer itself, but the pointed memory location in the heap. In this example that memory location in the heap was made to contain 3.14159. You can also define the pointer types. Our second example illustrates. It displays the squares from one to ten. {$M 16384,0,80000} type arrayType = array [1..10] of real; type arrayPtrType = ^arrayType; var A : arrayPtrType; i : integer; begin if SizeOf(arrayType) > MaxAvail then begin writeln ('Out of memory'); halt; end; New(A); for i := 1 to 10 do A^[i] := i*i; writeln (A^[9]); end. For an actual application using pointers, see the item "How can I copy a file in a Turbo Pascal program?" --------------------------------------------------------------------