琴弦过早损坏以及如何避免?
我正在使用 Delphi 2009,并使用以下代码段得到一些奇怪的错误:
var
Str : AnsiString;
CharPtr : PAnsiChar;
...
CharPtr := PAnsiChar (Str);
ExecuteInBackgroundThread (
procedure
begin
DoSomething (CharPtr);
end);
我猜测字符串在超出范围时被破坏,并且在某些计时条件下 DoSomething 将产生最奇怪的结果。所以第一个问题是:我说得对吗?
第二个问题是:如何避免字符串被破坏?执行此操作的正确方法是什么?
提前致谢。
I'm using Delphi 2009 and get some strange errors using the following code segment:
var
Str : AnsiString;
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
最有可能的是,是的。 Delphi 的 AnsiString 是引用计数的。当
Str
超出范围时,引用计数就会递减。如果引用计数达到零,则它占用的内存可以被重用。不使用指针,如下所示:
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.By not using pointers, like this:
只需使用:
一般规则很简单:直到最后一刻才使用 PChar。这样您就不需要过多考虑内存管理问题(嗯,主要是)。
另请参阅这篇精彩文章。
Just use:
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.
好吧,我想我可能已经明白了。
我使用的是匿名方法,因此编译器应该捕获我的局部变量。显然,它只捕获我在匿名方法中实际使用的变量。这意味着 CharPtr 被捕获,但 SendStr 未被捕获。因此,当 SendStr 超出范围时,它就会被破坏,并且 CharPtr 现在面临指向某些随机垃圾的危险。
通过以下修改,
一切似乎都工作正常。
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
everything seems to work fine.
为什么不按值传递字符串,而不是按指针/引用传递字符串?
Why not pass the string by value, rather than pointer/reference?