我正在使用Delphi 2009并使用以下代码段获得一些奇怪的错误:
var
Str : AnsiString;
CharPtr : PAnsiChar;
...
CharPtr := PAnsiChar (Str);
ExecuteInBackgroundThread (
procedure
begin
DoSomething (CharPtr);
end);
我猜测字符串在超出范围时会被破坏,并且在某些时间条件下,DoSomething会产生最奇怪的结果。所以第一个问题是:我是对的吗?
第二个问题是:我如何规避被破坏的字符串?这样做的正确方法是什么?
提前致谢。
答案 0 :(得分:7)
所以第一个问题是:我是对的吗?
很有可能,是的。德尔福的AnsiString是引用计数。当Str
超出范围时,引用计数会递减。如果引用计数达到零,则可以重用它占用的内存。
第二个问题是:我怎么能 避开字符串 遭到破坏?什么是正确的方法 对此?
不使用指针,如下:
var
Str : AnsiString;
...
ExecuteInBackgroundThread (
procedure
begin
DoSomething (Str);
end);
答案 1 :(得分:4)
只需使用:
DoSomething(PAnsiChar(Str));
一般规则很简单:直到最后一刻才使用PChar 。这样您就不需要过多地考虑内存管理问题(主要是)。
答案 2 :(得分:2)
好的,我想我可能已经弄清楚了。
我正在使用匿名方法,因此编译器应该捕获我的局部变量。显然,它只捕获我在匿名方法中实际使用的变量。这意味着CharPtr被捕获但不是SendStr。因此,当SendStr超出范围时,它会被破坏,CharPtr现在有可能指向一些随机垃圾。
进行以下修改
ExecuteInBackgroundThread (
procedure
begin
Log (Str);
DoSomething (CharPtr);
end);
一切似乎都运转良好。
答案 3 :(得分:0)
为什么不按值传递字符串,而不是指针/引用?