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

时间:2015-10-22 19:41:46

标签: delphi

使用:在英特尔酷睿i7-2820QM上运行的Delphi XE7 Update 1,TAwImageGrid,Windows 10 Professional。

此代码从数据库将图像加载到网格中:

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可以看看这个问题并提供答案,但其他德尔福大师也欢迎。

链接:

  1. TAwImageGrid组件源官方主页: https://svn.apada.nl/svn/NLDelphi-opensource/ngln/AwImageGrid/

  2. StackOverflow问题,它提供了对组件的良好介绍: Looking for a custom image grid

1 个答案:

答案 0 :(得分:2)

我可以重现您的发现并将其视为一个错误。

在制作组件时,我从D7复制了TStringList的实现,即使用指向不存在的大小固定数组的指针来存储项目的内部存储。奇怪的是,我找不到它的缺陷,但是D7的TStringList实现并没有产生这个bug。我想它可以做explained here

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