FreeBasic Reallocate 关键字
最后修改日期:2025 年 6 月 16 日
FreeBasic 的 Reallocate 关键字用于调整动态分配的内存块大小。它允许在可能的情况下,在保留现有数据的同时调整内存分配。
基本定义
Reallocate 更改先前分配的内存块的大小。它接受指向现有内存的指针和新大小作为参数。该函数返回指向重新分配内存块的指针。
如果新大小较大,则附加内存未初始化。如果较小,则会释放多余的内存。原始数据在旧大小和新大小中较小者范围内保留。
基本的 Reallocate 示例
本示例演示了 Reallocate 最简单的用法。
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 可与字符串缓冲区一起用于动态字符串操作。
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 也可与自定义结构体类型一起使用。
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 是否成功,因为它可能会失败。
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 可以通过缩小数组来减少内存使用。
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 处理多维数组
对于多维数组,重新分配需要仔细的指针处理。
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 更高效。它通常可以避免完整的内存复制。
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 通常更快,因为它通常可以在原地扩展内存而无需复制。内存块越大,性能差异就越大。
最佳实践
- 检查 NULL:始终验证 Reallocate 是否返回 NULL。
- 保留指针:使用临时变量存储结果。
- 大小计算:始终使用 SizeOf 以确保类型安全。
- 初始化:请记住新内存是未初始化的。
- 清理:不要忘记在使用完毕后调用 Deallocate。
本教程通过实际示例展示了 FreeBasic Reallocate 关键字在不同场景下的使用。