从指针复制数据?

3
...
  PAnalyzeInfo = ^TAnalyzeInfo;
  TAnalyzeInfo = record
    pPitch: array of Single;
    pEnergy: array of Single;
    pPitchAccent: array of Single;
    pEnergyAccent: array of Single;
    pDicAccent: array of Single;
    pScore: array of Single;
    pBoundary: Integer;
    szRecWord: array of array of AnsiChar;
    nRecWordNum: Integer;
    nFrameNum: Integer;
  end;
...

我有一个包含数据的 pDataSource: PAnalyzeInfo 变量,我想将其复制到一个新的独立变量 MyData : TAnalyzeInfo 中。

是否可以一次性复制整个结构,还是需要逐个添加?

3个回答

5
在Delphi中,你可以通过简单的赋值操作来复制记录,这得益于编译器的神奇处理。
MyData := DataSource^;

动态数组是引用计数的,所以只要您不需要真正的深度复制,赋值操作也会处理动态数组。通过简单的赋值,它们只是共享同一块内存。
如果您不想这样,可以逐个复制它们:
MyData.pPitch = Copy(pDataSource^.pPitch, Low(pDataSource^.pPitch), 
                                          High(pDataSource^.pPitch);

动态数组不使用写时复制。它们类似于字符串使用引用计数,但是当分配数组元素时,它不会像分配字符串字符时那样创建一个新的副本。 - Rob Kennedy

4

不,动态数组不能通过单个复制命令进行复制。您需要:

  1. 复制每个非数组字段
  2. 对于每个数组
    1. 在目标中创建一个正确大小的新数组
    2. 将数组成员复制到新数组中

如果数组是静态的,那么复制整个内存块将会更容易。


1
你可以使用在系统单元中声明的move过程: system.move(pDataSource^, MyData, sizeof(TAnalyzeInfo));

好的,但是在处理数组时需要小心。在记录中,数组只是指向实际数组数据的指针,因此新记录和原始记录将具有指向相同数组的成员。数组数据不会被复制 - 每个成员只有一个数组。 - Andreas Rejbrand
不是所有的数组,只有动态数组(没有边界)是指针。 - Marco van de Voort
1
不要这样做。问题中的每个结构中的数组都是动态数组,它们是引用并具有引用计数。使用Move进行复制将复制引用而不会更改引用计数;当只剩下一个引用指向这些数组(从处理其他副本时),这个剩余的副本将具有指向已释放数据的悬空指针。 - Barry Kelly
是的,所有都正确。请考虑开放/动态数组和引用计数限制。这个不太光彩的技巧只有在源代码持久存在且您只需要一个临时副本(例如仅供方便)并且仅引用数组元素中的值而没有任何修改时才是安全的。 - Hasan S

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接