如何将 MOVE 用于以记录为元素且其上有动态数组字段的动态数组?

2023-11-29

我正在使用 Delphi Rio,我的程序有很多动态数组操作。为了提高一些长数组复制的速度,我尝试使用 Move 。对于基本类型(实数、整数)的一维动态数组,我可以管理 Move 的使用,但对于以记录作为其元素的动态数组,并且该记录具有另一个动态数组字段,我很难使其工作。我对动态数组记录字段使用 MOVE 的方式,在发出命令后,这些字段继续指向源数组的原始源地址。

测试过程:array_A是动态记录数组,该记录的两个字段都是动态数组。发出 Move(array_A[0],B_array[0],sizeof(Array[0]) * length(arra_A)) 后,然后更改 array_B 动态数组字段中的值,这也会导致 array_A 的值发生变化!两者都指向同一个地址。如何使用 MOVE 改变这种行为?

看我的代码:

    program ProjArrayMove;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

Type

     Arrayint   = Tarray<Integer>;
     Arrayreal  = TArray<Real>;

     RECmember = record
           mcode       : integer;
           mname       : string[30];
           mdynarr_int  : arrayint;
           mdynarr_real : arrayreal;
     end;

     ArrayMember = array of RECMember;

     Procedure FillsRecord (var pRec : RECmember; pSize : integer; pFactor : real);
     // Given a pRec , fills each dynamic array fields with pSize numbers
     var
        idx : integer;
     begin
          setlength(pRec.mdynarr_int,pSize);
          setlength(pRec.mdynarr_real,pSize);
          with pRec do
          begin
               for idx := 0 to pSize - 1 do
               begin
                    mdynarr_int[idx]  := idx;
                    mdynarr_real[idx] := idx * (1.0 + pFactor);
               end;
          end;
     end;


     Procedure FillsArray  (var pArr : ArrayMember; pSizeArray, pSizeRec : integer; pChar : Char);
     // Given a array of records pArr  , fills the array with pSizeArray records
     var
        idx : integer;
     begin
           setlength(pArr,pSizeArray);

           //Fils first record - element 0
           FillsRecord(pArr[0],pSizeRec,2.3);
           pArr[0].mcode := 0;
           pArr[0].mname := '0' + pChar;

           //Fills major array with records , each record with dynamic arrays fields also filled
           for idx := 1 to High(pArr) do
           begin
                FillsRecord(pArr[idx],pSizeRec,idx * 2.3);
                pArr[idx].mcode := idx;
                pArr[idx].mname  := idx.ToString + StringOfChar(pChar,2);
           end;
     end;


     Procedure PrintArray(pArr : ArrayMember);
     // Given an array of records pArr, prints each element including the dynami array fields
     var
        i,j : integer;
     begin
           Writeln(stringofchar('=',20));
           for I := Low(pArr) to High(pArr) do
           begin
                 Write('Idx :' + i.ToString + ' ' );
                 Write('Code :' + pArr[i].mcode.ToString  + ' ' );
                 Write('Name :' + pArr[i].mname + '   ');
                 Write(' mdynarr_int :');
                 for j := Low(pArr[i].mdynarr_int) to High(pArr[i].mdynarr_int) do
                     Write(' ' + pArr[i].mdynarr_int[j].ToString);
                 Write(' mdynarr_real :');
                 for j := Low(pArr[i].mdynarr_real) to High(pArr[i].mdynarr_real) do
                     Write(' ' + FloatToStr(pArr[i].mdynarr_real[j]));
                 Writeln;
           end;
     end;

var
    larray_A, larray_B : ArrayMember;
    idx, lsizeA, lsize_int, lsize_real : integer;
begin
      try
          //Step 1 - Fills the first array with 10 records and its relaed dynamic arrays fields with 5 elements each
          FillsArray(larray_A,10,5, 'A');

          //Step 2- An attempt to ast copy elements of larray_A to larray_B
          Setlength(larray_B, length(larray_A));
          lsizeA := Sizeof(larray_A[0]);

          MOVE(larray_A[0], larray_B[0], length(larray_A) * lsizeA);

          Writeln('========== ARRAY A ==========');

          PrintArray(larray_A);
          readln;

          Writeln('========== ARRAY B ==========');

          PrintArray(larray_B);
          readln;

          //Now change values in item of array B
          larray_B[0].mcode := 777;
          larray_B[0].mname := 'B was changed';
          larray_B[0].mdynarr_int[0]  := 427;
          larray_B[0].mdynarr_real[0] := 784.96;

          Writeln('======= ARRAY B AFTER CHANGES ========');

          PrintArray(larray_B);
          readln;

          Writeln('====== VERIFYING IMPACT IN ARRAY A =======');

          PrintArray(larray_A);
          readln;

          //3-Attemp to use MOVE to copy contet of dynamic arrays fields in records member
          lsize_int := Sizeof(larray_A[0].mdynarr_int[0]);
          lsize_real:= Sizeof(larray_A[0].mdynarr_real[0]);

          for idx := Low(larray_B) to High(larray_B) do
          begin
                setlength(larray_B[idx].mdynarr_int,length(larray_A[idx].mdynarr_int));
                **MOVE(larray_A[idx].mdynarr_int[0],larray_B[idx].mdynarr_int[0],
                     lsize_int * length(larray_B[idx].mdynarr_int) );**

                setlength(larray_B[idx].mdynarr_real,length(larray_A[idx].mdynarr_real));
                MOVE(larray_A[idx].mdynarr_int[0],larray_B[idx].mdynarr_int[0],
                     lsize_real * length(larray_B[idx].mdynarr_real) );
          end;

          Writeln;
          Writeln;

          //Now change values in item of array B
          larray_B[0].mcode := 555;
          larray_B[0].mname := '2nd Change in B';
          larray_B[0].mdynarr_int[0]  := 10427;
          larray_B[0].mdynarr_real[0] := 10784.96;

          Writeln('======= ARRAY B AFTER 2nd CHANGES ========');

          PrintArray(larray_B);
          readln;

          Writeln('====== VERIFYING IMPACT IN ARRAY A =======');

          PrintArray(larray_A);
          readln;

          Writeln('==> It seems that MOVE in record fields of dynamic array type does not work as I expected - WHY ?');
          readln;

      except
        on E: Exception do
          Writeln(E.ClassName, ': ', E.Message);
      end;
end.

谢谢你们 !


您第一次致电Move获取内部数组引用的副本,但在编译器后面执行,因此会破坏引用计数。从那时起,你所做的一切都注定会失败。你不能使用Move关于所管理的数据。

要正确执行此操作,您需要如下代码:

type
  TMyRec = record
    Int: Integer;
    Arr: TArray<Integer>;
    function Clone: TMyRec;
  end;

function TMyRec.Clone: TMyRec;
begin
  Result.Int := Int;
  Result.Arr := Copy(Arr);
end;

function CloneRecArray(const Arr: array of TMyRec): TArray<TMyRec>;
var
  i: Integer;
begin
  SetLength(Result, Length(Arr));
  for i := 0 to High(Result) do
    Result[i] := Arr[i].Clone;
end;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将 MOVE 用于以记录为元素且其上有动态数组字段的动态数组? 的相关文章

  • 从 Delphi VCL 样式获取特定字形

    我想从 VCL 样式获取特定的位图 并将其设置为按钮上的图像 它实际上是帮助问号 在位图样式编辑器中是来自表单的 btnHelp 图像 要从 VCL 样式获取视觉元素 字形 您必须使用GetElementDetails和TCustomSty
  • 如何比较枚举类型集

    从某个时刻开始 我厌倦了编写设定条件 and or 因为对于更多的条件或更长的变量名 重新编写会变得笨拙且烦人 所以我开始写助手这样我就可以写ASet ContainsOne ceValue1 ceValue2 代替 ceValue1 in
  • 如何从该 JAVA 文件中提取 Delphi 类以与 Android 一起使用?

    我的Delphi XE7项目需要与FTDI FT311 Android 配件芯片 http www ftdichip com Products ICs FT311D html 他们帮助提供了一个 Android 演示 其中包括他们的 JAV
  • 为什么 Delphi 中的 ADO Next 记录处理速度变慢?

    我有一个多年前开发的 Delphi 4 程序 它使用Opus 直接访问 http sourceforge net projects directaccess 按顺序搜索 Microsoft Access 数据库并检索所需的记录 Delphi
  • 从其可执行文件的路径获取服务名称

    我有一个可执行文件的路径 它是一个正在运行的服务应用程序 例如 C Program Files x86 Someapp somesvc exe 我想停止并启动它 为此我想我需要获取服务的名称 如下所示 this https stackove
  • Delphi - Indy - 保存 GMail 草稿

    我一直在 Delphi 下使用 Indy 通过 gmail 帐户发送消息 使用 TIdSMTP 和 TIdMessage 组件 这绝对没问题 但是 我的客户请求将消息保存到 DRAFTS 文件夹 以便他在实际发送消息之前对 以编程方式创建的
  • 使用 Delphi 读取 Excel 电子表格

    我需要使用 Delphi 2010 读取和写入 Excel 电子表格 没什么花哨的 只需读取和写入不同工作表上特定单元格和范围的值 需要在没有安装 Excel 的情况下工作并支持 Excel 2007 我看过的一些东西 我尝试过使用ADO
  • MainFormOnTaskbar + 工具提示导致焦点窃取

    我使用 Delphi XE2 构建了下面的代码 它创建 Form1 Form1 立即创建 Form2 的实例 当我按下 Form2 上的按钮时 会创建第二个 Form2 现在 如果我将鼠标悬停在第二个 最上面的 Form2 上的按钮上 并等
  • 为什么 TImage 旋转我的图像?

    编写一个移动应用程序 它从安全网站提取图像 如下所示 第一个图像 提取不正确 注意网络版本与移动版本 第二个图像在网站上正确显示 但 Delphi TImage 由于某种原因正在旋转它我不明白为什么 旋转设置为 0 并且在 TImage 组
  • Windows 更新后 Active 设置为 False 时 TIdHttpServer 冻结

    我们有一个 Indy 版本 10 6 1 5235 TIdHttpServer 服务 多年来一直与 Delphi 2007 配合良好 在最新的 Windows 更新 KB4338815 和 KB4338830 之后 我们注意到当 TIdHt
  • VirtualStringTree 正确/推荐使用

    我已经使用 virtualstringtree 一段时间了 我将它用于两个不同的用途 第一个是用于选择 显示数据的普通树 第二个是作为网格来显示 SQL 语句的输出 我加载到树中的所有数据都来自数据库 对于树示例 我有一个 ParentId
  • 如何从窗体单元外部访问delphi控件?

    我试图从如下定义的过程中调用计时器的 Enabled 属性 procedure Slide Form TForm Show Boolean 并且没有固定的形式名称 例如 Form2 Timer 将表单的单位放入使用列表后 这可以工作 For
  • 我可以在 Delphi 中使用字符串“IsEmpty”方法吗

    内河码头文件 IsEmpty 方法 http docs embarcadero com products rad studio delphiAndcpp2009 HelpUpdate2 EN html delphivclwin32 Syst
  • Delphi 是否在构造对象之前分配变量?

    Delphi 是否在对象完全构造之前分配实例变量 换句话说 给定一个变量 var customer TCustomer nil 然后我们构造一个客户并将其分配给变量 customer TCustomer Create 有没有可能custom
  • 什么是代码页 0?

    我正在使用Delphi函数 StringCodePage 我在 COM 函数 Acrobat Annotation getContents 请参阅我的其他帖子 返回的字符串上调用它 它返回 0 0是什么 安西 代码页 0 是 CP ACP
  • 让线程在窗体关闭时保持运行

    我在我的应用程序上创建了一个同步线程 我想知道如果我关闭申请表 是否有办法让该线程保持打开状态 直到完成同步过程 调用线程的WaitFor方法在您的 DPR 文件中 之后Application Run线 如果线程已经运行完毕 那么WaitF
  • DBX 错误:驱动程序无法正确初始化

    我在跑步德尔福XE3 终极版 MySQL 数据库 这是我点击时收到的错误Test Connection 作为回应 我在 xampp 目录中找到了 libmysql 库 并将其复制到我的 System32 目录中 但这是行不通的 此消息指的是
  • Delphi:如何计算大文件的 SHA 哈希值

    您好 我需要生成 5 Gig 文件的 SHA 您知道有一个非基于字符串的 Delphi 库可以做到这一点吗 你应该使用DCPcrypt v2 http www cityinthesky co uk cryptography html读取缓冲
  • 在 tlistbox 中绘制缩略图

    在 DelphiXE 中 我使用 tFileOpenDialog 选择一个文件夹 然后在 tListBox 中列出该文件夹中的所有 jpg 文件 我允许将列表项拖放到列表中进行自定义排序 以便稍后按顺序显示它们 我希望能够在文件名旁边绘制图
  • 使用 (Object as TClass) 和 TClass(Object) 进行强制转换有什么区别

    有问题在哪里MyObj classnameis TMyClass classname 是真的并且TMyClass MyObj 有效但是 MyObj as TMyclass doSomething抛出转换错误 我真的不需要任何关于这些垃圾的帮

随机推荐

  • 使用 javascript 正则表达式替换和增加整数值

    给定以下字符串 XXXX Units 4 Test XXXX 我想替换每次出现的Unit x with Unit x 1 我正在尝试使用正则表达式来实现此目的 如名称所示Units需要首先进行字面匹配 我正在尝试这样的事情 test rep
  • Shiny:根据输入选择输入子集

    编辑 感谢您的帮助 我的代码存在多个问题 但主要问题是我缺少 Observe 语句 以下解决了问题 get ddf lt reactive filter poskick Name input player observe updateSel
  • iPhone AVCaptureDeviceInput 如何设置音频捕获的质量?

    以下代码在 44100 深度 2 处工作正常 一些检查和代码被删除 这似乎是默认值 由于这个界面可用 但没有很好的记录 有人知道如何更改默认质量吗 audioCaptureDevice AVCaptureDevice defaultDevi
  • 从交互式图表中抓取数据

    是否可以获取交互式图表背后的数据这个网页 抱歉 网站需要登录 当我用鼠标悬停在图表上时 数据就会显示出来 但是如何获取这些数据呢 以下是该网站 HTML 源代码的摘录
  • 如何防止 youtube iframe 从独立应用程序重定向到 Youtube 应用程序?

    我开发了一份网络杂志揭示js 当然 用户可以决定为他 她自己的智能手机或平板电脑创建快捷方式 创建一个独立的应用程序 该应用程序不会在普通浏览器中打开 带有网址栏 导航命令等 为此 我使用这段代码 一切正常 除了当我滑动到内容中有 YouT
  • 寻找可以在 WinForms 应用程序中播放 AVI 文件的组件(.NET 或 COM/ActiveX)[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 我正在寻找类似 Windows Media Player 控件之类的可以托管在表单上的东西 WMP 不适合我 因为我需要一个可以按顺序播放连续附加的
  • 使用箭头键移动 PictureBox - 处理 PictureBox 中的键盘事件

    我有一个PictureBox我使用下面的代码来移动我的对象 我需要在表单中添加一些按钮 但是当我启动程序时 箭头键在按钮中导航 而不是我的输入按键 我尝试过很多 像这样的方式PictureBox Focus and PictureBox S
  • 使用自定义字体而不包含在 info.plist ios 中

    在 iOS 中 如果我们想使用自定义字体 我们必须包含font ttf在应用程序包中并添加font ttf作为字体键的值信息列表 file 我想使用自定义字体 在设备中安装应用程序后 将从我的服务器下载其 ttf 文件 1 是否可以在我的应
  • Office Outlook Web Addin 不适用于 Office Client 2016

    我使用 Angular 5 版本开发了一个插件 我已经构建了它并使用 sercure http 部署在 Apache 服务器上 我通过使用不同的用户登录在 Office Web App 上测试了这个插件 我发现它按我的预期工作 但现在的问题
  • 将派生类型映射到 EF 中的同一个表

    以下简单的代码示例说明了相关场景 我有一个 Person 实体 它只是映射到数据库中的 Person 表 我正在使用默认的实体对象代码生成器 public partial class Person 我有一个从 Person 派生的 Pers
  • Smooch:如何进行依赖于回发的状态转换?

    我正在尝试根据 Smooch 回发有效负载将脚本从一种状态转换为另一种状态 但收到错误代码 H12 考虑这个例子https github com smooch smooch bot example 假设我修改了脚本https github
  • (8051) 检查是否设置了一位

    我正在为 8051 微控制器编写程序 在程序的第一部分中 我做了一些计算 并根据结果 我要么点亮 LED 要么不点亮 使用CLR P1 7 其中 P1 7 是微控制器中连接 LED 的端口 在程序的下一部分中 我想检索该位 也许将其存储在某
  • 如何在 Python 中进行 DNS 查找,包括引用 /etc/hosts?

    dnspython会很好地完成我的 DNS 查找 但它完全忽略了 etc hosts 是否有一个 python 库调用可以做正确的事情 即先签入etc hosts 否则只能回退到 DNS 查找 我不太确定你是否想要进行 DNS 查找your
  • 如何更改 ggplot 中美学层的顺序?

    如何更改美学层的顺序 这是和例子 dat lt tibble acc rep c 0 1 200 rt rnorm 400 0 5 0 1 dat gt ggplot aes x rt fill factor acc geom densit
  • 使用媒体会话 Web API 的媒体通知不适用于 Web 音频 API

    我正在尝试在我的 PWA 中针对当前播放的音频内容实现自定义通知 正如标题所述 我使用 Android v8 1 0 和 Google Chrome 应用程序 v68 0 x 根据this文章 The Media Session API i
  • 在 Identity 2.0 中扩展 IdentityUserRole

    因此 我的系统要求角色具有关联的到期日期 我已经实现了 Identity 2 0 框架 一切进展顺利 但我遇到了一个问题 让我怀疑我的结构 public class ApplicationUserRole IdentityUserRole
  • 如何防止ListView扩大窗口尺寸?

    我将 ListView 放在 View 的中间行 该视图包含在 SizeToContent 设置为 WidthAndHeight 的窗口中 ListView 最初是空的 但底层 ViewModel 在此过程中填充了此列表视图 中间的 Gri
  • 使用 Julia 和 gurobi 进行二次约束 MIQP

    这是试图回答以下问题 https matheducators stackexchange com questions 11757 small data sets with integral sample standard deviation
  • 函数参数传递和返回

    var foo bar function return this baz baz 1 function return typeof arguments 0 foo bar 为什么这段代码会返回undefined 我会假设arguments
  • 如何将 MOVE 用于以记录为元素且其上有动态数组字段的动态数组?

    我正在使用 Delphi Rio 我的程序有很多动态数组操作 为了提高一些长数组复制的速度 我尝试使用 Move 对于基本类型 实数 整数 的一维动态数组 我可以管理 Move 的使用 但对于以记录作为其元素的动态数组 并且该记录具有另一个