Continuing the series, I’ll just briefly touch on fill pointers. These are basically just convenience features that can be attached to one-dimensional arrays.
If a one-dimensional array (vector) has a fill pointer, it informs the system that the vector’s length is equal in value to the fill pointer. One might use this feature when incrementally filling a vector, maybe a cache. To avoid the cost of reallocation on resizing, you could create a large initial vector, but set the fill pointer to zero. Then, as elements are added to the vector, you increase the fill pointer.
The fill pointer does not forbid references to offsets of the vector that are above the limit of the fill pointer, it merely allows length to return something other than the actual length of the allocated vector. When printing a vector, no elements past the fill pointer are displayed. Other than those two cases, the fill pointer doesn’t have any other effect. Here’s a series of operations:
CL-USER> (defparameter *fvec* (make-array 10 :fill-pointer 4 :initial-element 1)) *FVEC* CL-USER> *fvec* #(1 1 1 1) CL-USER> (setf (aref *fvec* 6) 15) 15 CL-USER> (aref *fvec* 6) 15 CL-USER> (array-dimension *fvec* 0) 10 CL-USER> (length *fvec*) 4 CL-USER> (setf (fill-pointer *fvec*) 10) 10 CL-USER> *fvec* #(1 1 1 1 1 1 15 1 1 1)
You’ll notice that I can modify and retrieve elements past the end of the region the fill pointer declares as active. You’ll also see that array-dimension and length return different values.
If you use the fill-pointer accessor on a vector that doesn’t have a fill pointer, an error is raised. You can check whether or not a vector has a fill pointer with the function array-has-fill-pointer-p.