Pointer variables are not directly usable by many of the operators, functions, or procedures provided by IDL. You cannot, for example, do arithmetic on them or plot them. You can do these things with the heap variables referenced by such pointers, assuming that they contain appropriate data for the task at hand. Pointers exist to allow the construction of dynamic data structures that have lifetimes that are independent of the program scope they are created in.
There are 4 IDL operators that work with pointer variables: assignment, dereference, EQ, and NE. The remaining operators (addition, subtraction, etc.) do not make any sense for pointer types and are not defined.
Many non-computational functions and procedures in IDL do work with pointer variables. Examples are SIZE, N_ELEMENTS, HELP, and PRINT. It is worth noting that the only I/O allowed directly on pointer variables is default formatted output, where they are printed as a symbolic description of the heap variable they point at. This is merely a debugging aid for the IDL programmer—input/output of pointers does not make sense in general and is not allowed. Please note that this does not imply that I/O on the contents of non-pointer data held in heap variables is not allowed. Passing the contents of a heap variable that contains non-pointer data to the PRINT command is a simple example of this type of I/O.
Assignment
Assignment works in the expected manner—assigning a pointer to a variable gives you another variable with the same pointer. Hence, after executing the statements:
A = PTR_NEW(FINDGEN(10))
B = A
HELP, A, B
A and B both point at the same heap variable and we see the output:
A POINTER = <PtrHeapVar1>
B POINTER = <PtrHeapVar1>
Dereference
In order to get at the contents of a heap variable referenced by a pointer variable, you must use the dereference operator, which is * (the asterisk). The dereference operator precedes the variable dereferenced. For example, if you have entered the above assignments of the variables A and B:
PRINT, *B
IDL prints:
0.00000 1.00000 2.00000 3.00000 4.00000 5.00000
6.00000 7.00000 8.00000 9.00000
That is, IDL prints the contents of the heap variable pointed at by the pointer variable B.
Dereferencing Pointer Arrays
Note that the dereference operator requires a scalar pointer operand. This means that if you are working with a pointer array, you must specify which element to dereference. For example, create a three-element pointer array, allocating a new heap variable for each element:
ptarr = PTRARR(3, /ALLOCATE_HEAP)
To initialize this array such that the heap variable pointed at by the first pointer contains the integer zero, the second the integer one, and the third the integer two, you would use the following statement:
FOR I = 0,2 DO *ptarr[I] = I
Note: The dereference operator is dereferencing only element I of the array for each iteration. Similarly, to print the values of the heap variables pointed at by the pointers in ptarr, try the following:
PRINT, *ptarr
IDL prints:
% Expression must be a scalar in this context: PTARR.% Execution halted at: $MAIN$
To print the contents of the heap variables, use the statement:
FOR I = 0, N_ELEMENTS(ptarr)-1 DO PRINT, *ptarr[I]
Dereferencing Pointers to Pointers
The dereference operator can be applied as many times as necessary to access data pointed at indirectly via multiple pointers. For example, the statement:
A = PTR_NEW(PTR_NEW(47))
assigns to A a pointer to a pointer to a heap variable containing the value 47.
To print this value, use the following statement:
PRINT, **A
Dereferencing Pointers within Structures
If you have a structure field that contains a pointer, dereference the pointer by prepending the dereference operator to the front of the structure name. For example, if you define the following structure:
struct = {data:'10.0', pointer:ptr_new(20.0)}
you would use the following command to print the value of the heap variable pointed at by the pointer in the pointer field:
PRINT, *struct.pointer
Defining pointers to structures is another common practice. For example, if you define the following pointer:
ptstruct = PTR_NEW(struct)
you would use the following command to print the value of the heap variable pointed at by the pointer field of the struct structure, which is pointed at by ptstruct:
PRINT, *(*pstruct).pointer
Note that you must dereference both the pointer to the structure and the pointer within the structure.
Dereferencing the Null Pointer
It is an error to dereference the NULL pointer, an invalid pointer, or a non-pointer. These cases all generate errors that stop IDL execution. For example:
PRINT, *45
IDL prints:
% Pointer type required in this context: <INT( 45)>.
% Execution halted at: $MAIN$
For example:
A = PTR_NEW() & PRINT, *A
IDL prints:
% Unable to dereference NULL pointer: A.
% Execution halted at: $MAIN$
For example:
A = PTR_NEW(23) & PTR_FREE, A & PRINT, *A
IDL prints:
% Invalid pointer: A.
% Execution halted at: $MAIN$
Equality and Inequality
The EQ and NE operators allow you to compare pointers to see if they point at the same heap variable. For example:
A = PTR_NEW(23)
B = A
C = PTR_NEW()
PRINT, 'A EQ B: ', A EQ B & $
PRINT, 'A NE B: ', A NE B & $
PRINT, 'A EQ C: ', A EQ C & $
PRINT, 'C EQ NULL: ', C EQ PTR_NEW() & $
PRINT, 'C NE NULL:', C NE PTR_NEW()
IDL prints:
A EQ B: 1
A NE B: 0
A EQ C: 0
C EQ NULL: 1
C NE NULL: 0