为何Pascal中复制动态记录数组后修改一个会影响另一个?
动态数组复制后元素同步变化的原因分析
Pascal代码示例
type TMen=record code:String; name:String; end; TMenLst=array of TMen; TForm10 = class(TForm) Button1: TButton; Memo1: TMemo; procedure Button1Click(Sender: TObject); private { Private declarations } a,b:TMenLst; public { Public declarations } procedure show(v:TMenLst); end; var Form10: TForm10; implementation {$R *.dfm} procedure TForm10.Button1Click(Sender: TObject); begin SetLength(a,3); a[0].code:='code1'; a[0].name:='name1'; a[1].code:='code2'; a[1].name:='name2'; a[2].code:='code3'; a[2].name:='name3'; SetLength(b,3); CopyMemory(@b,@a,SizeOf(a)); //Move(a, b, SizeOf(a)); a[0].code:='aaaa'; a[0].name:='bbbb'; show(a); show(b); end; procedure TForm10.show(v: TMenLst); var I:integer; begin for I := Low(v) to High(v) do Memo1.Lines.Add('code:'+a[I].code+' '+'name:'+a[I].name); Memo1.Lines.Add('---------------------'); end;
运行结果
code:aaaa name:bbbb code:code2 name:name2 code:code3 name:name3 --------------------- code:aaaa name:bbbb code:code2 name:name2 code:code3 name:name3 ---------------------
问题解答
这是因为Delphi中的动态数组是引用类型,而非值类型。
动态数组变量本身只是一个指针,指向堆内存中实际存储数组元素的区域。你用CopyMemory或Move执行的复制操作,仅仅是把这个指针的值拷贝给了b,并没有复制数组里的实际元素数据。这就导致a和b指向了同一块堆内存——它们本质上是同一个数组的两个"别名"。
所以当你修改a的元素时,实际是直接修改了这块共享内存里的数据,b作为指向同一块内存的引用,读取到的自然就是修改后的值。
另外补充:你的show函数存在一个小问题,循环中使用的是a[I]而非传入的参数v[I],这会导致无论传入a还是b,最终显示的都是a的内容,但这并不影响本次现象的核心逻辑。
内容的提问来源于stack exchange,提问作者pangzhenguang
相关产品推荐
相关产品推荐

