Delphi通过引用传递参数或通过值/复制 [英] Delphi passing parameters by reference or by value/copy
问题描述
上下文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屋!