对静态数组指针, 虽然在声明之处并没有分配内存, 但这个指针应该分配多少内存是有定数的.
这种情况, 我们应该用 New 和 Dispose 来分配与释放内存. 譬如:
这种情况, 我们应该用 New 和 Dispose 来分配与释放内存. 譬如:
type TArr1 = array[0..255] of Char; TArr2 = array[0..255] of Integer; var arr1: ^TArr1; arr2: ^TArr2; begin New(arr1); New(arr2); arr1^ := '万一的 Delphi 博客'; ShowMessageFmt('%s%s', [arr1^[0], arr1^[1]]); {万一} // ShowMessageFmt('%s%s', [arr1[0], arr1[1]]); {这样也可以} arr2[Low(arr2^)] := Low(Integer); {第一个元素赋最小值} arr2[High(arr2^)] := MaxInt; {第一个元素赋最大值} ShowMessageFmt('%d, %d', [arr2[0], arr2[255]]); {-2147483648, 2147483647} Dispose(arr1); Dispose(arr2); end;给已知大小的指针分配内存应该用 New, 上面的例子是关于静态数组指针的, 后面要提到的结构体(记录)的指针也是如此.
New 的本质也函数调用 GetMem, 但不需要我们指定大小了.那怎么给动态数组的指针分配内存呢? 其实动态数组变量本身就是个指针, 就不要绕来绕去再给它弄指针了.
不过有一个理念还是满重要的, 那就是我们可以把一个无类型指针转换为动态数组类型, 譬如:type TArr = array of Integer; var p: Pointer; begin GetMemory(p, 3 * SizeOf(Integer)); {分配能容纳 3 个 Integer 的空间} {这和 3 个元素的 TArr 的大小是一样的, 但使用时需要进行类型转换} TArr(p)[0] := Random(100); TArr(p)[1] := Random(100); TArr(p)[2] := Random(100); ShowMessageFmt('%d,%d,%d', [TArr(p)[0], TArr(p)[1], TArr(p)[2]]); {0,3,86} FreeMemory(p); end;
这里用到了 GetMemory 和 FreeMemory, 对分配无类型指针这是比较常用的先总结下:
New 是给已知大小的指针分配内存;
GetMem 主要是给无类型指针分配内存;
尽量使用 GetMemory 来代替 GetMem.
还有个 AllocMem 和它们又有什么区别呢?
AllocMem 分配内存后会同时初始化(为空), GetMem 则不会, 先验证下:var p1,p2: Pointer; begin p1 := AllocMem(256); ShowMessage(PChar(p1)); {这里会显示为空} FreeMemory(p1); p2 := GetMemory(256); ShowMessage(PChar(p2)); {这里会显示一些垃圾数据, 内容取决与在分配以前该地址的内容} FreeMemory(p2); end;关于 FreeMemory 与 FreeMem 的区别:
1、FreeMemory 会检查是否为 nil 再 FreeMem, 这有点类似: Free 与 Destroy;
2、FreeMem 还有个默认参数可以指定要释放的内存大小, 不指定就全部释放(没必要只释放一部分吧);
3、New 对应的 Dispose 也可以用 FreeMem 或 FreeMemory 代替.
尽量使用 FreeMemory 来释放 GetMem、GetMemory、AllocMem、ReallocMem、ReallocMemory 分配的内存.
ReallocMem、ReallocMemory 是在已分配的内存的基础上重新分配内存, 它俩差不多 ReallocMemory 比 ReallocMem 多一个 nil 判断, 尽量使用 ReallocMemory 吧. 譬如:type TArr = array[0..MaxListSize] of Char; PArr = ^TArr; var arr: PArr; i: Integer; begin arr := GetMemory(5); for i := 0 to 4 do arr[i] := Chr(65+i); ShowMessage(PChar(arr)); {ABCDE} arr := ReallocMemory(arr, 26); ShowMessage(PChar(arr)); {ABCDE} for i := 0 to 25 do arr[i] := Chr(65+i); ShowMessage(PChar(arr)); {ABCDEFGHIJKLMNOPQRSTUVWXYZ} end;