[英]Stack Overflow in Delphi
我在 StackOverflow.com 上發布了我的 Stack Overflow 問題。 最好的諷刺!
反正。 我在我的 SkypeReply 事件處理程序上調用這個過程,它被觸發了很多:
Procedure OnCategoryRename;
Var
CategoryID : Integer;
sCtgName : String;
Begin
if (AnsiContainsStr(pCommand.Reply,'GROUP')) and (AnsiContainsStr(pCommand.Reply,'DISPLAYNAME')) then
begin
sCtgName := pCommand.Reply;
Delete(sCtgName,1,Pos('GROUP',sCtgName)+5);
CategoryID := StrToInt(Trim(LeftStr(sCtgName,Pos(' ',sCtgName))));
sCtgName := GetCategoryByID(CategoryID).DisplayName; // Removing THIS line does not produce a Stack Overflow!
ShowMessage(sCtgName);
end;
這樣做的想法是遍歷我的 Skype 組列表,以查看已重命名的組。 AFAIK 那不重要,因為我的 SO 已被追蹤到出現在這里
Function GetCategoryByID(ID : Integer):IGroup;
Var
I : Integer;
Category : IGroup;
Begin
// Make the default result nil
Result := nil;
// Loop thru the CUSTOM CATEGORIES of the ONLY SKYPE CONTROL used in this project
// (which 100% positive IS attached ;) )
for I := 1 to frmMain.Skype.CustomGroups.Count do
Begin
// The Category Variable
Category := frmMain.Skype.CustomGroups.Item[I];
// If the current category ID returned by the loop matches the passed ID
if Category.Id = ID then
begin
// Return the Category as Result (IGroup)
Result := Category;
// Exit the function.
Exit;
end;
End;
End;
當我在 Result := Category; 處設置斷點時; 和 Single Step thru,這 2 行會一遍又一遍地執行,緊隨其后!
當我注釋掉sCtgName := GetCategoryByID(CategoryID).DisplayName;
在第一個代碼片段中,沒有溢出,消息會顯示一次應該的。 但是, GetCategoryByID
是我寫的一個函數,我也寫了一個類似的函數,它工作得很好(GetCategoryByName),所以我不明白為什么它決定重復
// Return the Category as Result (IGroup)
Result := Category;
// Exit the function.
Exit;
一遍又一遍。
編輯:這是您如何重現它: https : //gist.github.com/813389
編輯:這是我的 CallStack,根據要求:
編輯2:更多信息:
確保在關閉“優化”、“堆棧幀”和“使用調試 .dcu”的情況下編譯您的項目,以獲得最詳細的調用堆棧。 然后在此處發布您遇到堆棧溢出時獲得的調用堆棧(如果您無法從中識別問題的性質)。
無限遞歸可能會導致堆棧溢出。
當您編寫包含事件處理程序的代碼時,您必須非常小心。 正如大衛所說,你可以做的一件事是幫助你調試它,而不是跳過這樣的調用。 F7 進入呼叫。
您可以做的另一件事是在函數 GetCategoryById 的頂部放置一個斷點。 現在看看你的調用堆棧。 你看到堆棧中重復的名字了嗎? 這應該說得很清楚了。
您的問題中沒有顯示的內容:您在此處發布的“OnCategoryRename”函數是從“TForm.Skype1Reply”回調調用的子函數。
要看到這一點,我必須單擊您的 github 鏈接 - 但我認為這是您問題的一個重點。
我的猜測:
我認為一個快速而骯臟的解決方法是改變
sCtgName := GetCategoryByID(CategoryID).DisplayName; // Removing THIS line does not produce a Stack Overflow!
與
sCtgName := //find another way to get the new name, which you can probably get from your ICommand object
pCommand.Reply.ReadDataFromReplyAndGetNewDisplayName;
將來,我建議您針對此類問題發布完整的代碼示例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.