过早的弦破坏以及如何避免它?

时间:2009-10-06 10:28:22

标签: multithreading delphi delphi-2009 anonymous-methods

我正在使用Delphi 2009并使用以下代码段获得一些奇怪的错误:

var
  Str     : AnsiString;
  CharPtr : PAnsiChar;
...
CharPtr := PAnsiChar (Str);
ExecuteInBackgroundThread (
  procedure
  begin
  DoSomething (CharPtr);
  end);

我猜测字符串在超出范围时会被破坏,并且在某些时间条件下,DoSomething会产生最奇怪的结果。所以第一个问题是:我是对的吗?

第二个问题是:我如何规避被破坏的字符串?这样做的正确方法是什么?

提前致谢。

4 个答案:

答案 0 :(得分:7)

  

所以第一个问题是:我是对的吗?

很有可能,是的。德尔福的AnsiString是引用计数。当Str超出范围时,引用计数会递减。如果引用计数达到零,则可以重用它占用的内存。

  

第二个问题是:我怎么能   避开字符串   遭到破坏?什么是正确的方法   对此?

不使用指针,如下:

var
  Str     : AnsiString;
...
ExecuteInBackgroundThread (
  procedure
  begin
  DoSomething (Str);
  end);

答案 1 :(得分:4)

只需使用:

DoSomething(PAnsiChar(Str));

一般规则很简单:直到最后一刻才使用PChar 。这样您就不需要过多地考虑内存管理问题(主要是)。

另见this great article

答案 2 :(得分:2)

好的,我想我可能已经弄清楚了。

我正在使用匿名方法,因此编译器应该捕获我的局部变量。显然,它只捕获我在匿名方法中实际使用的变量。这意味着CharPtr被捕获但不是SendStr。因此,当SendStr超出范围时,它会被破坏,CharPtr现在有可能指向一些随机垃圾。

进行以下修改

ExecuteInBackgroundThread (
  procedure
  begin
  Log (Str);
  DoSomething (CharPtr);
  end);
一切似乎都运转良好。

答案 3 :(得分:0)

为什么不按值传递字符串,而不是指针/引用?