【问题标题】:Copy on write for array of records写入时复制记录数组
【发布时间】:2014-11-04 12:18:55
【问题描述】:

写时复制语义是否适用于动态记录数组?

如何正确复制记录数组?

这就够了吗?:

type
  recordA = Record
    Y:integer;
  end;
var x: array of recordA;
    b: array of recordA;
    item: recordA;
begin
  SetLength(x, 2);
  item.Y:= 2;
  x[0] := item;
  item.Y:= 5;
  x[1] := item;
  //Copying
  b:= x;

复制完成后,我需要重置第一个数组:

SetLength(x, 0);

我可以这样做吗?

【问题讨论】:

  • 您的代码可以工作(但我相信您已经尝试过了。)所以我不确定您到底在问什么。
  • delphi 6 不在这里抱怨不兼容的类型b:= x;,因为你没有声明像:x,b: array of recordA;
  • @bummi:确实。两个数组的类型不同,不应该是赋值兼容的。

标签: delphi record delphi-6 copy-on-write


【解决方案1】:

动态数组不支持写时复制 (CoW) 语义。在您的示例中无关紧要,但在其他情况下很重要。

如果您需要复制动态数组的内容,请使用Copy 函数。这是一个演示动态数组分配和复制之间区别的示例:

procedure TestCopy;
type
  recordA = Record
    Y:integer;
  end;
  arrayA = array of recordA;

var x, b, c: arrayA;
    item: recordA;

begin
  SetLength(x, 2);
  item.Y:= 2;
  x[0] := item;
  item.Y:= 5;
  x[1] := item;

  b:= x;
  x[0].Y:= 4;
  Writeln(b[0].Y, ' -- ', x[0].Y);

  b:= Copy(x);
  x[0].Y:= 8;
  Writeln(b[0].Y, ' -- ', x[0].Y);
end;

【讨论】:

  • 没关系,因为我的代码中有SetLength(x, 0);
  • 没错,费利佩。当原始副本将在之后立即销毁时,没有理由制作副本。直接在b 中构造数组会更直接,或者放弃b 并继续使用x;您不需要两个变量来构成 single 数组。
  • @RobKennedy 实际上我使用这种方式是因为有多个执行线程处理同一个数组。当工作线程向主线程发出信号时,主线程复制数组(将其复制到缓冲区)并将“主”数组归零给工作线程再次填充它。由于线程争用,我只是序列化“复制和重置”部分。因此,我需要了解 Copy on Write
  • 你可以说动态数组支持“Copy-on-SetLength”。您甚至可以使用SetLength 将数组设置为其当前长度。这将保证一个唯一的参考。所以它可以有效地归结为复制数组的迂回方式。
猜你喜欢
  • 2014-08-12
  • 2018-09-27
  • 1970-01-01
  • 1970-01-01
  • 2011-08-18
  • 1970-01-01
  • 1970-01-01
  • 2011-07-23
  • 2021-07-26
相关资源
最近更新 更多