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])); {
结果是: 257257257257}
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 来释放 GetMemGetMemoryAllocMemReallocMemReallocMemory 分配的内存.

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 一次行初始化; 应该用 GetMemGetMemoryAllocMemReallocMemReallocMemory 等用多少申请多少.
需要注意的是, 重新分配内存也可能是越分越少; 如果越分越大应该可以保证以前数据的存在.
这在 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;
--------------------------------------------------------------------------------

这好像又让人费解, 只有一个元素的数组能干什么?
应该这样理解: 仅仅这一个元素就足够指示数据的起始点和数据元素的大小和规律了.

另外的 SysGetMemSysFreeMemSysAllocMemSysReallocMem 四个函数, 应该是上面这些函数的底层实现, 在使用 Delphi 默认内存管理器的情况下, 我们还是不要直接使用它们

posted on 2010-10-15 19:02  o无尘o  阅读(277)  评论(0编辑  收藏  举报