TShellTreeView 内存泄漏

TShellTreeView memory leak

我正在使用 MadExcept 来跟踪内存泄漏。如果我将 TShellTreeView 放在表单上并且 运行 应用程序 MadExcept 报告内存泄漏。只是打开和关闭,没有别的。我在 XE8 下使用 XE6 包,因为这是最后一个发布的 AFAIK。

我知道以前的 delphi 版本存在一些问题,但我认为这些问题已在 XE6 软件包中修复。

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

有什么想法吗?

是的,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 报告没有泄漏。

您无法实现同样的效果意味着您没有执行修改后的代码。也许您正在使用运行时包并且没有重新编译修改后的代码。或许还有另一种解释。无论如何,我完全清楚你未能消除泄漏是因为你仍然是 运行 原始未修改的代码。