开发者

Premature string destruction and how to avoid it?

I'm using Delphi 2009 and get some strange errors using the following code segment:

var
  Str     : AnsiStr开发者_StackOverflow社区ing;
  CharPtr : PAnsiChar;
...
CharPtr := PAnsiChar (Str);
ExecuteInBackgroundThread (
  procedure
  begin
  DoSomething (CharPtr);
  end);

I'm guessing that the string is destructed when falling out of scope and under some timing conditions DoSomething will yield the strangest results. So the first question is: am I right?

Second question is: How can I circumvent the string being destructed? What's the proper way to do this?

Thanks in advance.


So the first question is: am I right?

Most likely, yes. Delphi's AnsiString is reference counted. When Str goes out of scope, the reference count is decremented. If the reference count reaches zero then the memory it occupied may be reused.

Second question is: How can I circumvent the string being destructed? What's the proper way to to this?

By not using pointers, like this:

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


Just use:

DoSomething(PAnsiChar(Str));

General rule is simple: do not use PChar until at the very last moment. This way you don't need to think too much about memory management issues (well, mostly).

See also this great article.


Okay, I think I might have figured it out.

I'm using an anonymous method, so the compiler should capture my local variables. Apparently, it does only capture the variables that I actually use in the anonymous method. That means that CharPtr is captured but not SendStr. So, when SendStr falls out of scope it is destructed and CharPtr is now in danger of pointing to some random garbage.

With the following modification

ExecuteInBackgroundThread (
  procedure
  begin
  Log (Str);
  DoSomething (CharPtr);
  end);

everything seems to work fine.


Why not pass the string by value, rather than pointer/reference?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜