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
关键字在不同场景下的使用。