TAwImageGrid -程序泄漏内存,如果最后一个图像被删除



使用:Delphi XE7 Update 1, TAwImageGrid, Windows 10 Professional运行在Intel酷睿i7-2820QM.

下面的代码将图片从数据库加载到网格中:

var
  s, w: String;
  r: Integer;
  ms: TMemoryStream;
  bmp: TBitmap;
begin
  r := uqProj_Search.RecordCount;
  // Load images
  for r := imgGrid.Count - 1 downto 0 do
    imgGrid.Items.Images[r].Free;
  imgGrid.Clear;
  ms := TMemoryStream.Create;
  try
    while not(uqProj_Search.Eof) do
    begin
      r := uqProj_Search.FieldByName('row_id').AsInteger;
      // :proj_id
      uqImg_S.ParamByName('proj_id').AsInteger := r;
      uqImg_S.Prepared := True;
      uqImg_S.Open;
      ms.Clear;
      uqImg_Simg.SaveToStream(ms);
      uqImg_S.Close;
      ms.Position := 0;
      bmp := TBitmap.Create;
      try
        bmp.LoadFromStream(ms);
        imgGrid.Items.Add(IntToStr(r));
        imgGrid.Items.Images[imgGrid.Count - 1] := TBitmap.Create;
        imgGrid.Items.Images[imgGrid.Count - 1].Assign(bmp);
      finally
        bmp.Free;
      end;
      uqProj_Search.Next;
    end;
  finally
    ms.Free;
  end;
end;

我在KeyDown事件中有以下代码(当Del键被按下时调用):

procedure TfmSrchRec.imgGridKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
var
  x, p: Integer;
  AFormat: Word;
  AData: THandle;
  APalette: HPalette;
begin
  x := imgGrid.ItemIndex;
  p := StrToInt(imgGrid.Items.Strings[x]);
  if (x = -1) then
    Exit;
  if (UpCase(Char(Key)) = 'C') and (Shift = [ssCtrl]) then
  begin
    // Clipboard.Assign(imgGrid.Images[imgGrid.ItemIndex])
    TBitmap(imgGrid.Images[x]).Dormant;
    TBitmap(imgGrid.Images[x]).SaveToClipboardFormat(AFormat, AData, APalette);
    Clipboard.SetAsHandle(AFormat, AData);
  end
  else if (Key = VK_DELETE) then
  begin
    imgGrid.Items.Images[x].Free;
    imgGrid.Items.Delete(x);
  end;
end;

释放OnClose事件中的内存:

procedure TfmSrchRec.FormClose(Sender: TObject; var Action: TCloseAction);
var
  r: Integer;
begin
  for r := imgGrid.Count - 1 downto 0 do
    imgGrid.Items.Images[r].Free;
end;

问题来了:

从网格中删除图像后,如果该图像是最后剩余的图像,则关闭程序将产生以下错误消息:

---------------------------
Unexpected Memory Leak
---------------------------
An unexpected memory leak has occurred. The unexpected small block leaks are:

61 - 68 bytes: Unknown x 1

---------------------------
OK   
---------------------------

如果在关闭应用程序之前网格中有剩余的图像,则不会发生错误。我在项目启动时(在DPR文件中)有ReportMemoryLeaksOnShutDown := True

我猜这个错误与组件的代码有关,而不是我使用它的方式。我希望TAwImageGrid组件作者NGLN可以看看这个问题并提供答案,但也欢迎其他Delphi专家。

链接:

  1. TAwImageGrid组件源码官方主页:https://github.com/NGLN/AwImageGrid

  2. StackOverflow问题,给出了一个很好的介绍组件:寻找自定义图像网格

我可以重现你的发现并认为这是一个bug。

当制作组件时,我从D7复制了TStringList的实现,即通过使用指向不存在的固定大小数组的指针来存储项目。奇怪的是,我找不到它的缺陷,但D7的TStringList实现并没有产生这个bug。我想它与这里解释的有关。

我看到TStringList在XE2中的实现更改为使用动态数组。当我将组件的代码更改为相同的设计时,内存泄漏就消失了。所以我也会修改开源代码,但目前您可以自己做。

最新更新