2010-06-07 104 views
1

執行Delphi字符串複製時,是否需要分配內存?在Delphi字符串複製之前需要分配內存嗎?

我有一個函數將Windows消息發佈到我的應用程序中的另一個表單。它看起來像這樣:

// Note: PThreadMessage = ^TThreadMessage; TThreadMessage = String; 

function PostMyMessage(aStr : string); 
var 
    gMsgPtr : PThreadMessage; 
    gStrLen : Integer; 
begin 
    New(gMsgPtr); 
    gStrLen := StrLen(PWideChar(aMsg)); 
    gMsgPtr^ := Copy(aMsg, 0, gStrLen); 
    PostMessage(ParentHandle, WM_LOGFILE, aLevel, Integer(gMsgPtr)); 

    // Prevent Delphi from freeing this memory before consumed. 
    LParam(gMsgPtr) := 0; 
end; 

回答

0

你並不需要分配內存複製字符串,但你不希望一個指針傳遞給在這種情況下,德爾福字符串。你想傳遞一個PChar,(也就是一個C字符串),並且你必須爲它分配內存。

3

您不需要分配任何內存。事實上,你甚至不需要撥打Copy。簡單的字符串分配就足夠了;引用計數將正確跟蹤acorss多個線程。您也不需要清除gMsgPtr;因爲它不是string類型的變量,所以編譯器不會爲其插入任何清理代碼。

begin 
    New(gMsgPtr); 
    gMsgPtr^ := aMsg; 
    PostMessage(ParentHandle, wm_LogFile, aLevel, LParam(gMsgPtr)); 
end; 

如果你想打電話Copy反正你不需要先計算長度。它會自動將索引參數限制到最大允許範圍。當你想要求「剩下的字符串」時,你可以簡單地通過MaxInt作爲第三個參數,Copy知道該怎麼做。同樣,對於第二個參數,自動增加任何值至少爲1,即最低有效字符索引。

+0

我一定錯過了一些東西。將aMsg分配給gMsgPtr會增加字符串的引用計數。執行PostMessage後,引用計數會減少。當消息的方法處理程序最終得到執行時,是不是有可能在LParam中傳遞的字符串不再指向有效內存(又被釋放了)? – 2010-06-08 07:51:06

+0

@Lieven,在進入該函數後,引用計數必須至少爲1(用於保存在'aMsg'中的引用)。對'gMsgPtr ^'的賦值增加了一個引用,所以現在至少爲2.當這個函數返回時,'aMsg'中的引用消失,但由於'gMsgPtr ^',計數仍然至少爲1。當消息處理程序運行時,它將調用Dispose(PThreadMessage(lParam)),並且引用計數將再次遞減,可能釋放該字符串。這裏顯示的代碼不會釋放'gMsgPtr';該內存的所有權被轉移到消息的收件人。 – 2010-06-08 14:32:25

+0

我明白了。我沒有想到這個變量被聲明爲PThreadMessage io TThreadMessage。謝謝你的解釋。 – 2010-06-08 14:43:43