Delphi通过引用传递参数或通过值/复制 [英] Delphi passing parameters by reference or by value/copy

查看:496
本文介绍了Delphi通过引用传递参数或通过值/复制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

上下文1

var text:String;

text:='hello';

myFunc(text);

Context2

function myFunc(mytext:String);
var textcopy:String;
begin

    textcopy:=mytext;

end;

myFunc Context1,局部变量 mytext 指向Context2之外的内存?或 mytext 在范围内有自己的内存空间,并且使用相同内容的文本填充/复制 ?我可能错过了一些非常基本的东西,因为我收到访问冲突错误。

myFunc on the Context2 was called from the Context1, the local variable mytext is pointing to a memory outside the Context2? or the mytext have have their own memory space inside the scope, and filled/copied with the same content of the text? I'm probably missing something really basic, because I'm getting a access violation error.

有什么办法明确指定一个函数是否应该通过引用或值接收参数,然后像C那样复制?我不知道我在做什么。

There's any way to specify explicitly if a function should receive parameters by reference or by value, copying then like in C? I'm not sure about how I'm doing it.

推荐答案

Delphi字符串的内存管理有点不寻常。在您调用 myFunc(text)之后,分配 textcopy:= mytext ,所有三个变量(文本 mytext textcopy )将指向同一个地址,原始的字符串。

Memory management for Delphi strings is a little unusual. After you call myFunc(text), and assign textcopy := mytext, all three variables (text, mytext and textcopy) will be pointing to the same address, that of the original string.

但是只要您使用其中一个变量来更改字符串,Delphi会克隆幕后的字符串,您的更改将应用​​于副本。另外两个变量仍然指向原来的,所以它们保持不变。所以上下文2中所做的任何改变都不会在上下文1中看到 - 这个写时复制技巧有效地给你一个值得一提的语义。所有这些字符串都是引用计数的,一旦所有引用超出范围,就会自动释放。

But as soon as you use one of these variables to make changes to the string, Delphi clones the string behind the scenes, and your changes are applied to the copy. The other two variables still point to the original, so they remain unchanged. So any changes made in Context 2 will not be seen in Context 1 - this "copy-on-write" mechanic effectively gives you pass-by-value semantics. All of these strings are reference-counted, and will be freed automatically once all references go out of scope.

但是,有一个例外。如果您使用指针访问字符串,而不是字符串操作,则将绕过复制步骤,并且您的更改将影响原始文本。您还将绕过引用计数逻辑,并可能会导致指向释放内存块的指针。这可能是你的访问冲突背后的原因,但是我不能说没有更多的细节/更多的代码。

However, there is an exception. If you access the string using pointers, rather than string operations, you'll bypass the copying step and your changes will affect the original. You'll also bypass the reference counting logic, and potentially end up with a pointer to a deallocated block of memory. This may be the reason behind your access violation, but I couldn't say without more details / more code.

如果你想要引用传递,将你的函数声明为code> myFunc(var mytext:String)。如果要强制Delphi复制字符串,而不是等待修改,可以使用 System.UniqueString

If you want reference passing, declare your function as myFunc(var mytext: String). If you want to force Delphi to copy the string, instead of waiting until it's modified, you can use System.UniqueString.

这篇关于Delphi通过引用传递参数或通过值/复制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆