ZetCode

FreeBasic Reallocate 关键字

最后修改日期:2025 年 6 月 16 日

FreeBasic 的 Reallocate 关键字用于调整动态分配的内存块大小。它允许在可能的情况下,在保留现有数据的同时调整内存分配。

基本定义

Reallocate 更改先前分配的内存块的大小。它接受指向现有内存的指针和新大小作为参数。该函数返回指向重新分配内存块的指针。

如果新大小较大,则附加内存未初始化。如果较小,则会释放多余的内存。原始数据在旧大小和新大小中较小者范围内保留。

基本的 Reallocate 示例

本示例演示了 Reallocate 最简单的用法。

reallocate_basic.bas
Dim p As Integer Ptr = Allocate(10 * SizeOf(Integer))

For i As Integer = 0 To 9
    p[i] = i * 10
Next

' Resize the array to hold 15 elements
p = Reallocate(p, 15 * SizeOf(Integer))

' Initialize new elements
For i As Integer = 10 To 14
    p[i] = i * 10
Next

' Print all elements
For i As Integer = 0 To 14
    Print p[i]
Next

Deallocate(p)

在这里,我们首先为 10 个整数分配内存并将它们填充值。然后我们将内存块的大小调整为容纳 15 个整数。原始值得以保留,我们初始化了新元素。

使用字符串进行 Reallocate

Reallocate 可与字符串缓冲区一起用于动态字符串操作。

reallocate_string.bas
Dim buffer As ZString Ptr = Allocate(20)
*buffer = "Hello, there!"

Print "Original: "; *buffer
Print "Length: "; Len(*buffer)

' Resize buffer to hold longer string
buffer = Reallocate(buffer, 50)
*buffer = "Hello, FreeBasic Programming Language!"

Print "Resized: "; *buffer
Print "New length: "; Len(*buffer)

Deallocate(buffer)

此示例展示了如何调整字符串缓冲区的大小。我们首先为短字符串分配 20 字节,然后将其调整为 50 字节以容纳更长的字符串。原始内容在被我们覆盖之前得以保留。

使用结构体进行 Reallocate

Reallocate 也可与自定义结构体类型一起使用。

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

Dim people As Person Ptr = Allocate(3 * SizeOf(Person))

' Initialize first three people
people[0].name = "Alice": people[0].age = 25
people[1].name = "Bob": people[1].age = 30
people[2].name = "Charlie": people[2].age = 35

' Resize to hold five people
people = Reallocate(people, 5 * SizeOf(Person))

' Initialize new people
people[3].name = "David": people[3].age = 40
people[4].name = "Eve": people[4].age = 45

' Print all
For i As Integer = 0 To 4
    Print people[i].name; " is "; people[i].age; " years old"
Next

Deallocate(people)

此代码演示了如何调整结构体数组的大小。我们从为 3 个 Person 结构体分配内存开始,然后调整大小以容纳 5 个。原始数据保持不变,我们可以向扩展的数组添加新元素。

带错误检查的 Reallocate

始终检查 Reallocate 是否成功,因为它可能会失败。

reallocate_error.bas
Dim p As Integer Ptr = Allocate(100 * SizeOf(Integer))

If p = 0 Then
    Print "Initial allocation failed"
    End
End If

' Try to resize to very large block
Dim newPtr As Integer Ptr = Reallocate(p, 1000000000 * SizeOf(Integer))

If newPtr = 0 Then
    Print "Reallocation failed - keeping original block"
    ' Continue with original pointer
Else
    p = newPtr
    Print "Reallocation succeeded"
End If

Deallocate(p)

此示例显示了正确的错误处理。我们检查了初始分配和重新分配的结果。如果重新分配失败,我们可以继续使用原始内存块或妥善处理错误。

使用 Reallocate 缩小数组

Reallocate 可以通过缩小数组来减少内存使用。

reallocate_shrink.bas
Dim arr As Double Ptr = Allocate(1000 * SizeOf(Double))

' Fill array with values
For i As Integer = 0 To 999
    arr[i] = Rnd() * 100
Next

' We only need first 100 elements now
arr = Reallocate(arr, 100 * SizeOf(Double))

' Verify the first elements are preserved
For i As Integer = 0 To 99
    Print arr[i]
Next

Deallocate(arr)

在这里,我们分配了一个大数组,然后当不再需要所有空间时将其缩小到一个较小的尺寸。第一个元素保持不变,而多余的内存被释放。

使用 Reallocate 处理多维数组

对于多维数组,重新分配需要仔细的指针处理。

reallocate_2d.bas
Dim rows As Integer = 3, cols As Integer = 4
Dim matrix As Integer Ptr Ptr = Allocate(rows * SizeOf(Integer Ptr))

' Allocate each row
For i As Integer = 0 To rows - 1
    matrix[i] = Allocate(cols * SizeOf(Integer))
    For j As Integer = 0 To cols - 1
        matrix[i][j] = i * cols + j
    Next
Next

' Resize to more rows
rows = 5
matrix = Reallocate(matrix, rows * SizeOf(Integer Ptr))

' Allocate new rows
For i As Integer = 3 To rows - 1
    matrix[i] = Allocate(cols * SizeOf(Integer))
    For j As Integer = 0 To cols - 1
        matrix[i][j] = i * cols + j
    Next
Next

' Print all elements
For i As Integer = 0 To rows - 1
    For j As Integer = 0 To cols - 1
        Print Using "####"; matrix[i][j];
    Next
    Print
Next

' Cleanup
For i As Integer = 0 To rows - 1
    Deallocate(matrix[i])
Next
Deallocate(matrix)

这个复杂的示例展示了如何调整二维数组的大小。我们首先分配一个 3x4 的矩阵,然后将其调整为 5 行。原始行得到保留,我们分配并初始化新行。每行必须单独管理。

Reallocate 与 Allocate/Free 的对比

对于调整内存块大小,Reallocate 比手动 Allocate/Copy/Free 更高效。它通常可以避免完整的内存复制。

reallocate_vs_manual.bas
Dim size As Integer = 1000000
Dim p1 As Integer Ptr = Allocate(size * SizeOf(Integer))
Dim p2 As Integer Ptr

' Fill with data
For i As Integer = 0 To size - 1
    p1[i] = i
Next

' Method 1: Using Reallocate
Dim t As Double = Timer
p1 = Reallocate(p1, 2 * size * SizeOf(Integer))
Print "Reallocate time: "; Timer - t

' Method 2: Manual allocate/copy/free
t = Timer
p2 = Allocate(2 * size * SizeOf(Integer))
For i As Integer = 0 To size - 1
    p2[i] = p1[i]
Next
Deallocate(p1)
Print "Manual time: "; Timer - t

Deallocate(p2)

此基准测试将 Reallocate 与手动内存管理进行了比较。Reallocate 通常更快,因为它通常可以在原地扩展内存而无需复制。内存块越大,性能差异就越大。

最佳实践

本教程通过实际示例展示了 FreeBasic Reallocate 关键字在不同场景下的使用。

作者

我叫 Jan Bodnar,是一名充满热情的程序员,拥有丰富的编程经验。我自 2007 年起就开始撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出所有 FreeBasic 教程