FillChar - 填充字节
--------------------------------------------------------------------------------
var
s: array[0..9] of Char;
begin
FillChar(s,SizeOf(s),'a');
ShowMessage(s); {aaaaaaaaaa}
end;
--------------------------------------------------------------------------------
var
arr: array[0..3] of Word;
i: Integer;
begin
FillChar(arr, Length(arr) * SizeOf(Word), 1);
{每个字节填充个 1 ; 现在每个 Word 的二进制是: 00000001 00000001}
for i := 0 to 3 do
ShowMessage(IntToStr(arr[i])); {结果是: 257、257、257、257}
end;
--------------------------------------------------------------------------------
其它常用内存操作函数:
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;
--------------------------------------------------------------------------------
注意上面这个例子中 TArr 类型, 它被定义成一个足够大的数组; 这种数组留出了足够的可能性, 但一般不会全部用到.
我们一般只使用这种数组的指针, 否则一初始化将会内存不足而当机.
即便是使用其指针, 也不能用 New 一次行初始化; 应该用 GetMem、GetMemory、AllocMem、ReallocMem、ReallocMemory 等用多少申请多少.
需要注意的是, 重新分配内存也可能是越分越少; 如果越分越大应该可以保证以前数据的存在.
这在 VCL 中 TList 类用到的理念.
如果你在心里上接受不了那么大一个数组(其实没事, 一个指针才多大? 我们只使用其指针), 也可以这样:
--------------------------------------------------------------------------------
type
TArr = array[0..0] 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;
--------------------------------------------------------------------------------
这好像又让人费解, 只有一个元素的数组能干什么?
应该这样理解: 仅仅这一个元素就足够指示数据的起始点和数据元素的大小和规律了.
另外的 SysGetMem、SysFreeMem、SysAllocMem、SysReallocMem 四个函数, 应该是上面这些函数的底层实现, 在使用 Delphi 默认内存管理器的情况下, 我们还是不要直接使用它们.