ZetCode

FreeBasic Preserve Keyword

Last modified October 18, 2026

The FreeBasic Preserve keyword is used with Redim to resize dynamic arrays while keeping their existing contents. Without Preserve, resizing an array erases all its elements.

Basic Definition

In FreeBasic, Preserve is a modifier for the Redim statement. It ensures that existing array elements are preserved when changing the array's dimensions.

With multi-dimensional arrays, Preserve is only safe when increasing the upper bound of the first dimension. Changing other dimensions may move or scramble the data. It is essential for maintaining data integrity when working with dynamic arrays.

Basic Array Resizing

This example shows the difference between resizing with and without Preserve.

preserve_basic.bas
Dim arr() As Integer
Redim arr(2)
arr(0) = 1
arr(1) = 2
arr(2) = 3

Print "Before Redim (no Preserve):"
For i As Integer = LBound(arr) To UBound(arr)
  Print arr(i);
Next
Print

Redim arr(4)  ' Resize without Preserve (reinitializes contents)
Print "After Redim (no Preserve):"
For i As Integer = LBound(arr) To UBound(arr)
  Print arr(i);
Next
Print

Dim arr2() As Integer
Redim arr2(2)
arr2(0) = 1
arr2(1) = 2
arr2(2) = 3

Redim Preserve arr2(4)  ' Resize with Preserve
Print "With Preserve:"
For i As Integer = LBound(arr2) To UBound(arr2)
  Print arr2(i);
Next

The first array loses its values when resized without Preserve. The second array keeps its original values in the resized array. New elements are initialized to zero for numeric types.

Preserving String Arrays

The Preserve keyword works similarly with string arrays.

preserve_strings.bas
Dim names() As String
Redim names(2)
names(0) = "Alice"
names(1) = "Bob"
names(2) = "Charlie"

Redim Preserve names(5)
names(3) = "David"
names(4) = "Eve"

For i As Integer = LBound(names) To UBound(names)
    Print i; ": "; names(i)
Next

This example shows how string arrays preserve their contents when resized. Original elements remain intact while new elements are empty strings by default. We then fill some of the new positions.

Multi-dimensional Arrays

With multi-dimensional arrays, the upper bound of the first dimension can be increased with Preserve. Changing the last dimension is not safe: the data is stored in row-major order, so the existing values get rearranged.

preserve_multidim.bas
Dim matrix() As Integer
Redim matrix(1 To 2, 1 To 2)
matrix(1, 1) = 1
matrix(1, 2) = 2
matrix(2, 1) = 3
matrix(2, 2) = 4

Redim Preserve matrix(1 To 3, 1 To 2)  ' Only first dimension grows safely

' Fill new elements
matrix(3, 1) = 5
matrix(3, 2) = 6

For i As Integer = 1 To 3
  For j As Integer = 1 To 2
    Print matrix(i, j); " ";
  Next
  Print
Next

This demonstrates resizing a 2D array while preserving contents. Here the first dimension grows from 2 to 3 rows and the existing values stay in place. Changing the last dimension instead would rearrange the stored values, so it should be avoided.

Preserve with User-Defined Types

Arrays of user-defined types can also be preserved during resizing.

preserve_udt.bas
Type Person
    name As String
    age As Integer
End Type

Dim people() As Person
Redim people(2)

people(0).name = "Alice" : people(0).age = 25
people(1).name = "Bob" : people(1).age = 30

Redim Preserve people(4)
people(2).name = "Charlie" : people(2).age = 35

For i As Integer = LBound(people) To UBound(people)
    If Len(people(i).name) > 0 Then
        Print people(i).name; " ("; people(i).age; ")"
    Else
        Print "[Empty]"
    End If
Next

This example shows preserving an array of custom types. Existing Person records remain intact after resizing. New elements are initialized with default values (empty string for name, 0 for age).

Performance Considerations

Using Preserve has some performance implications worth noting.

preserve_performance.bas
' Declare as variable-length (dynamic) arrays
Dim bigArray() As Integer
Dim newArray() As Integer

' Allocate initial sizes (moves them to the heap, avoiding stack warnings)
ReDim bigArray(1000000)
ReDim newArray(2000000)

' Fill array with values
For i As Integer = LBound(bigArray) To UBound(bigArray)
    bigArray(i) = i
Next

' Time resizing with Preserve
Dim t As Double = Timer
ReDim Preserve bigArray(2000000)
Print "Time to resize with Preserve: "; Timer - t; " seconds"

' Compare to creating new array
Dim t2 As Double = Timer
' newArray is already allocated above, but if you wanted a fresh alloc:
' ReDim newArray(2000000) ' (uncomment if benchmarking allocation time)

For i As Integer = 0 To 1000000
    newArray(i) = i
Next
Print "Time to create new array: "; Timer - t2; " seconds"

This benchmark times a Preserve resize against a plain fill loop over an array that was already allocated, so it does not measure allocation cost on an equal footing. Preserve may need to copy existing elements when the memory cannot be extended in place. For frequent resizing, consider alternative data structures.

Error Handling with Preserve

It is important to handle potential errors when using Preserve.

preserve_errors.bas
Dim arr() As Integer
Redim arr(2)
arr(0) = 1
arr(1) = 2
arr(2) = 3

' Shrink the array with Preserve; the kept elements stay intact
On Error Goto error_handler
Redim Preserve arr(1)
Print "Resize successful: "; arr(0); arr(1)
Goto finished

error_handler:
Print "Error code: "; Err
Goto finished

finished:

This example shows that shrinking an array with Preserve succeeds: the elements up to the new upper bound keep their values, and the elements beyond it are discarded. The error handler is a safety net for unexpected failures. Always check array bounds before resizing.

Best Practices

This tutorial covered the FreeBasic Preserve keyword with practical examples showing its usage in different scenarios.

Author

My name is Jan Bodnar. I am a programmer and technical writer who has been publishing programming articles since 2007. To date I have authored over 1,400 articles and eight e-books, and I have many years of experience teaching programming.

List all FreeBasic Tutorials.