Delphi 的内存操作函数(5): 复制内存

时间:2023-01-06 20:04:46

MoveMemory、CopyMemory 的功能类似, 都是复制内存, 都是调用 Move 过程;
MoveMemory、CopyMemory 操作指针; Move 操作实体.
还要注意, 它们的参数位置不一样!


{例1}
var
  buf1,buf2: array[0..9] of AnsiChar;
begin
  buf1 := '0123456789';
  buf2 := 'abcdefghij';

  Move(buf2[2], buf1[4], 5); // system.move(被拷贝的地址,目的地址,长度)
  ShowMessage(buf1); {0123cdefg9}
  ShowMessage(buf2); {abcdefghij}
end;

{例2}
var
  buf1,buf2: array[0..9] of AnsiChar;
begin
  buf1 := '0123456789';
  buf2 := 'abcdefghij';

  CopyMemory(@buf2[2], @buf1[4], 5);
  ShowMessage(buf1); {0123456789}
  ShowMessage(buf2); {ab45678hij}
end;

{例3}
var
  s1,s2: TStringStream; {两个字符串流}
begin
  s1 := TStringStream.Create;
  s2 := TStringStream.Create;
  {向第一个字符串流写入}
  s1.WriteString('万一的 Delphi 博客');
  ShowMessage(s1.DataString); {万一的 Delphi 博客}
  {设置第二个字符串流的大小}
  s2.SetSize(6);
  {从第一个流复制到第二个流}
  CopyMemory(s2.Memory, s1.Memory, s2.Size);
  ShowMessage(s2.DataString); {万一的}
  s1.Free;
  s2.Free;
end;

这里仅仅是为了测试, 如果真的使用 TMemoryStream、TStringStream 等流类, 它们自身提供的复制操作更方便.

//===================================

 {删除的过程就是把当前元素后面的所有元素向前挪动一个位置}
  if Index < FCount then
    System.Move(FList^[Index + 1], FList^[Index], (FCount - Index) * SizeOf(Pointer));
raise Exception.CreateFmt('非法的 Index:%d', [Index]);// Exception 可以直接.create('要抛出的异常提示')
{如果参数大于元素总数没有赋值的用空字符填充}
  {如果参数小于元素总数, 删除多余的元素      }
  if Value > FCount then
    FillChar(FList^[FCount], (Value - FCount) * SizeOf(Pointer), 0)
  else
    for i := FCount - 1 downto Value do
      Delete(I);