While the basic arrays discussed in P1.8 have a fixed size defined at compile time, Dynamic Arrays allow you to change their size during program execution, making them far more flexible for real-world data handling.
1. Dynamic Arrays
A Dynamic Array is a special kind of pointer that manages a list of contiguous elements of the same type in heap memory.
A. Declaration
Unlike fixed arrays (e.g., array[1..10] of Integer), the declaration of a dynamic array does not specify a range.
program DynamicArrayDemo;
var
// Syntax: array of DataType
Names: array of String;
Scores: array of Integer;
begin
// ...
end.
B. Allocation and Resizing (SetLength)
The size of a dynamic array is allocated and changed at run time using the SetLength procedure. When you call SetLength, any existing data in the array is preserved, if possible.
- Indexing: Dynamic arrays are always zero-based (the first element is index 0).
begin
// 1. Allocate space for 5 elements (indices 0 to 4)
SetLength(Scores, 5);
Scores[0] := 98;
Scores[4] := 75; // The last element
Writeln('Initial size: ', Length(Scores)); // Output: 5
// 2. Resize to 10 elements (indices 0 to 9). Data in 0-4 is preserved.
SetLength(Scores, 10);
Scores[9] := 100; // New last element
Writeln('New size: ', Length(Scores)); // Output: 10
// 3. Clear the array (free the memory on the heap)
SetLength(Scores, 0);
// Note: The array variable itself (Scores) is a pointer on the stack,
// but the data (the list of integers) is on the heap.
end.
C. Useful Array Functions
| Function | Purpose | Example | Result |
Length(A) | Returns the current number of elements in array A. | Length(Names) | 5 |
High(A) | Returns the index of the last element (i.e., Length(A) - 1). | High(Names) | 4 |
Low(A) | Returns the index of the first element. (Always 0 for dynamic arrays). | Low(Names) | 0 |
2. Stack vs. Heap Memory
Understanding where your data is stored is fundamental to programming efficiency and avoiding memory issues. All memory used by a program is generally divided into two areas: the Stack and the Heap.
A. Stack Memory
- Storage: Stores local variables (simple types like
Integer,Boolean, and pointers/references to complex data). - Mechanism: Follows a LIFO (Last-In, First-Out) structure, like a stack of plates. When a procedure is called, its local variables are pushed onto the stack; when the procedure exits, they are instantly and automatically popped off.
- Speed: Extremely Fast (CPU caches are often optimized for the stack).
- Lifespan: Tied directly to the execution scope (procedure call).
procedure MyRoutine;
var
A: Integer; // Integer A is stored on the Stack
B: array of String; // B is a pointer stored on the Stack
begin
A := 42;
SetLength(B, 10); // The 10 strings are stored on the Heap
// ...
end; // When MyRoutine ends, A is automatically freed from the Stack.
B. Heap Memory
- Storage: Stores all dynamically allocated data, including Dynamic Arrays, Class Instances (Objects), and any memory allocated by low-level pointer routines (
New). - Mechanism: Unstructured memory pool. Data is allocated manually by the program (e.g., via
SetLengthorCreate) and requires management. - Speed: Slower than the Stack (due to allocation/deallocation overhead).
- Lifespan: Persists until it is explicitly released by the program or the program terminates.
Memory Leak: If memory is allocated on the Heap and the program loses the reference (the pointer on the Stack) without freeing the Heap memory, that memory becomes permanently unusable until the program ends. This is called a Memory Leak. In modern Object Pascal, classes often manage their own heap memory, reducing this risk (as we’ll see in P2.4).
3. Copying Dynamic Arrays
When you assign one dynamic array variable to another, Pascal copies the reference, not the data.
var
A: array of Integer;
B: array of Integer;
begin
SetLength(A, 2);
A[0] := 1;
B := A; // B now points to the SAME memory block as A
B[0] := 99; // Changes the data in the memory block
Writeln(A[0]); // Output: 99 (A sees the change made via B)
// To make a true, deep copy, you would typically write a loop or use
// a utility function like System.SysUtils.Copy.
end.
