The Delphi Bug List

Entry No.
575
VCL - Win32 - ComCtrls - TListView
The TCustomListView has a memory leak bug in the Clear method of the unit-specific type TSubItems in the ComCtrls unit.
1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 4.03 5.0 5.01 6.0 6.01 6.02 Kylix 1.0
N/AN/AN/AN/AN/AAbsentAbsentAbsentAbsentExistsExistsExistsExistsFixedN/A
Description
Reported by Arjen de Ruijter; checked by Jordan Russell
Description and cause:
When using Subitems.Add en .Delete, the overridden TSubItems.Add and TSubItems.Delete maintain the Local FImageIndices well, but when using the Clear method of the parent Class TStrings, then things go wrong because there is no overriden TSubItems.Clear and the FImageIndices will not be cleared.

This bug is especially memory-eating when you use TCustomListView.OwnerDataFetch:

unit ComCtrls, line 12636-12645:
   FTempItem.FSubItems.Clear;
   ....<cut>....
   OwnerDataFetch(FTempItem, Request);
and add SubItems in the overridden OwnerDataFetch or the OnData-event implemented in the native TCustomListView.OwnerDataFetch. In that case the FImageIndices grows without bound, because the TempItem is never destroyed during the use of TCustomListView.

Greg Chapman's comment from borland.public.delphi.vcl.components.using (go here to read the whole article/thread on Google):

...There is a memory leak when using OwnerData mode under D5. The problem comes from the TSubItems class which holds the subitems of the temporary list item used when requesting data for the listview to display. If you have the source to comctrls.pas, you'll see that TSubItems has a TList member called FImageIndices. An element is added to this list everytime you add an element to TSubItems. However, when you clear TSubItems, FImageIndices is not cleared. If you look at TCustomListView.GetItem, you'll see that each time FTempItem is initialized (which is each time the virtual listview needs to draw a row), FSubItems.Clear is called, which will not clear FImageIndices. Then, OwnerDataFetch is called which adds the current row's subitems (assuming there are any) to FTempItem.SubItems, which will add new items to FImageIndices. So FImageIndices grows without limit. The fix is to provide an overridden TSubItems.Clear method (Clear is a virtual method of TStringList):
procedure TSubItems.Clear;
begin
  inherited Clear;
  FImageIndices.Clear;
end;

Note from checker:
I can confirm that Greg Chapman's fix works. Without it, one of my applications leaks several hundred kilobytes each time I drag the scroll bar on its owner-data list view!

User-contributed comments
Steve Trefethen
12 Feb 2002  06:39 AM GMT
This is fixed in Delphi 6.0 update 2.
Latest update of this entry: 2002-02-28

Post a comment on this bug


Index page
Delphi Bug List home page
The Delphi Bug Lists are presently maintained by Jordan Russell, who has taken over this task from Reinier Sterkenburg since August 2000.
All feedback is appreciated. See also the feedback section of the Delphi Bug List home page.