While basic Delphi arrays have a fixed size defined at compile time, most real-world applications require managing data that grows or shrinks dynamically.
1. Dynamic Arrays
A Dynamic Array is an array whose size can be determined and changed at runtime. It is the modern, preferred way to handle lists of simple data types in Object Pascal.
- Declaration: Declared using
array of DataTypewithout specifying the range. - Initialization: The size must be set using the
SetLengthprocedure. - Indexing: Dynamic array indexing starts at 0.
Example: Declaring and Sizing a Dynamic Array
// In the interface type section:
type
TIntegerArray = array of Integer; // Defines a dynamic array type
// In a procedure:
procedure TForm1.ManageNumbers;
var
Scores: TIntegerArray; // Variable based on the dynamic array type
i: Integer;
begin
// Set the length to 5 elements (indices 0 to 4)
SetLength(Scores, 5);
// Assign values
Scores[0] := 95;
Scores[4] := 70;
// Resize the array to 10 elements. Existing data is preserved.
SetLength(Scores, 10);
// Use High() and Low() for bounds
for i := Low(Scores) to High(Scores) do
begin
// Process data...
end;
// To completely clear the array and free memory:
SetLength(Scores, 0);
end;
2. The TStringList Class
The TStringList class is one of the most frequently used non-visual VCL classes. It provides a highly optimized, dynamic collection designed specifically for managing lists of strings.
- Inheritance:
TStringListis a descendant ofTObject, requiring explicit creation and destruction (or reliance on object ownership). - Use Cases: Used to manage data in components like
TMemo,TListBox, andTComboBox(via theirLinesorItemsproperty).
A. Basic TStringList Operations
| Method/Property | Purpose | Example |
Create | Constructor. Allocates memory for the list object. | MyList := TStringList.Create; |
Add(S) | Adds a string S to the end of the list. | MyList.Add('New Item'); |
Clear | Removes all strings from the list. | MyList.Clear; |
Count | Integer property. Returns the current number of strings in the list. | Total := MyList.Count; |
Strings[Index] | Property. Accesses or modifies the string at the zero-based index. | FirstItem := MyList.Strings[0]; |
Free | Destructor call. Releases the memory allocated by Create. | MyList.Free; |
B. Managing the TStringList Lifecycle
Since TStringList is a class (an object), you must handle its creation and destruction to prevent memory leaks.
procedure TForm1.UseStringList;
var
Names: TStringList;
i: Integer;
begin
// 1. Create (Allocate) the object
Names := TStringList.Create;
try // 2. Use try..finally to guarantee destruction
Names.Add('Sam');
Names.Add('Kelly');
for i := 0 to Names.Count - 1 do
ShowMessage(Names.Strings[i]);
finally
// 3. Free (Destroy) the object, even if an exception occurs above
Names.Free;
end;
end;
Key Pattern: The
try...finallyblock is the standard pattern in Object Pascal for resource management, guaranteeing that the cleanup code (theFreecall) is executed regardless of how thetryblock exits.
3. Name-Value Pairs (TStringList Features)
A common use of TStringList is to manage name-value pairs (e.g., configuration settings like Username=John, Theme=Dark).
AddPair(Name, Value): Adds a pair separated by the delimiter (usually=).Values[Name]: Allows you to retrieve the value associated with the given name.
// ... inside a TStringList procedure ...
Names.Add('User=John');
Names.Add('Role=Admin');
// Retrieve the value for 'Role'
var UserRole := Names.Values['Role']; // UserRole will be 'Admin'
4. Generic Collections (Generics.Collections)
For managing lists of objects or strongly-typed, non-string data, modern Delphi introduced Generics.
TList<T>: A generic list that can hold objects of any specified typeT.TDictionary<K, V>: A key-value collection, where both the key (K) and value (V) can be strongly-typed.
// To use generics, you must add System.Generics.Collections to your unit's uses clause
// Example: A strongly-typed list of Integers
var
MyNumbers: TList<Integer>;
begin
MyNumbers := TList<Integer>.Create;
try
MyNumbers.Add(50);
MyNumbers.Add(100);
// MyNumbers.Add('Hello'); // This would cause a compile-time error (Type safety)
finally
MyNumbers.Free;
end;
end;
