TShellTreeView 内存泄漏问题

3
我正在使用MadExcept来跟踪内存泄漏。如果我在窗体上放置一个TShellTreeView并运行应用程序,MadExcept会报告内存泄漏。只是打开和关闭,没有别的操作。我正在使用XE8下的XE6包,因为这是我所知道的最后一个版本。

我知道以前的Delphi版本存在一些问题,但我认为这些问题在XE6包中已经得到解决。

这是应用程序关闭后显示的MadExcept窗口:

MadExcept ScreenShot

任何想法?
1个回答

3

是的,madExcept是正确的,这是可以预料的,因为它的质量非常高。这确实是您使用的代码中的缺陷。它看起来像这样:

function CreateRootFolder(RootFolder: TShellFolder; OldRoot : TRoot;
  var NewRoot: TRoot): TShellFolder;
var
  P: PWideChar;
  NewPIDL: PItemIDList;
  NumChars,
  Flags,
  HR: LongWord;
  ErrorMsg : string;
begin
  HR := S_FALSE;
  if GetEnumValue(TypeInfo(TRootFolder), NewRoot) >= 0 then
  begin
    HR := SHGetSpecialFolderLocation(
            0,
            nFolder[GetCSIDLType(NewRoot)],
            NewPIDL);
  end
  else if Length(NewRoot) > 0 then
  begin
    if NewRoot[Length(NewRoot)] = ':' then NewRoot := NewRoot + '\';
    NumChars := Length(NewRoot);
    Flags := 0;
    P := StringToOleStr(NewRoot);
    HR := DesktopShellFolder.ParseDisplayName(0, nil, P, NumChars, NewPIDL, Flags);
  end;

  if HR <> S_OK then
  begin
    { TODO : Remove the next line? }
    // Result := RootFolder;
    ErrorMsg := Format( SErrorSettingPath, [ NewRoot ] );
    NewRoot := OldRoot;
    raise Exception.Create( ErrorMsg );
  end;

  Result := CreateRootFromPIDL(NewPIDL);
  if Assigned(RootFolder) then RootFolder.Free;
end;

在这两个分支中,销毁NewPIDL的责任在调用方。代码本身不会销毁它。可以从文档中看到这一点: 修改函数的最后部分,使其如下所示:
Result := CreateRootFromPIDL(NewPIDL);
if Assigned(RootFolder) then RootFolder.Free;
CoTaskMemFree(NewPIDL);

我可以确认已经测试了这个更改。我测试了原始代码并复现了您报告的泄漏情况。然后按上述描述更改了代码,madExcept没有报告泄漏。

你无法达到相同的效果意味着你没有执行修改后的代码。也许你正在使用运行时包,并且没有重新编译修改后的代码。或者可能有另一种解释。不管怎样,对我来说完全清楚,你未能消除泄漏是因为你仍在运行原始未经修改的代码。


您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Ken White
我相信如果你释放PIDL,代码就不会泄漏。 - David Heffernan
@David:所以我的更改是根据你的建议吗?如果是,那么代码仍然存在泄漏问题。 - lda
是的,我已经添加了它。NewPIDL 在这一行中被创建:Result := CreateRootFromPIDL(NewPIDL); 它应该在这一行中被释放:CoTaskMemFree(NewPIDL); - lda
好的,你是对的。它是在更上面创建的。也许现在对我来说已经太晚了,但我仍然不明白你的意思。我已经将该块添加到函数中,但它仍然无法正常工作。那么,还有其他事情需要做吗?如果没有,那么泄漏仍然存在。 - lda
显示剩余10条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接