Articles   Members Online:
-Article/Tip Search
-News Group Search over 21 Million news group articles.
Member Area
-Account Center
-Top 10 NEW!!
-Submit Article/Tip
-Forums Upgraded!!
-My Articles
-Edit Information
-Become a Member
-Why sign up!
-Chat Online!
-Indexes NEW!!
-Build your resume
-Find a job
-Post a job
-Resume Search
-Link to us
Visit Embarcadero
Embarcadero Community
How to store records in a TList when their number is unknown until runtime Turn on/off line numbers in source code. Switch to Orginial background IDE or DSP color Comment or reply to this aritlce/tip for discussion. Bookmark this article to my favorite article(s). Print this article
Delphi 2.x
User Rating
No Votes
# Votes
DSP, Administrator
Reference URL:
			Author: Tomas Rutkauskas

How to store records in a TList when their number is unknown until runtime


To store a number of records ( probably number unknown until runtime ), one would 
use a Delphi TList object. TList is basically an array of pointers that grows as 
needed, up to 16K pointers can be stored in a TList. It will accept anything that 
even remotely looks like a pointer (a pointer is an address, normally of a bit of 
data that has been allocated from the heap, and needs 4 bytes to store the 
address). If you work with dynamically allocated data items you need to take care 
of releasing this memory to the system heap again if it is no longer needed. It is 
easy to forget this, especially if the data items are kept in a list. It is thus a 
good idea to derive a custom list class from TList that takes care of freeing the 
memory for the items it stores automatically.

1   type
2     TRecord = record { the record type }
3       { ... }
4     end;
5     PRecord = ^TRecord; { pointer type for pointers to TRecords }
6     TRecordList = class(TList) { a customized version of TList to hold PRecord 
7   pointers }
8     private
9       procedure SetRecord(index: Integer; Ptr: PRecord);
10      function GetRecord(index: Integer): PRecord;
11    public
12      procedure Clear;
13      destructor Destroy; override;
14      property Records[i: Integer]: PRecord read GetRecord write SetRecord;
15    end;
17    {Methods of TRecordList}
19  procedure TRecordList.SetRecord(index: Integer; Ptr: PRecord);
20  var
21    p: PRecord;
22  begin
23    { get the pointer currently in slot index }
24    p := Records[index];
25    if p <> Ptr then
26    begin
27      { if it is different from the one we are asked to put into this slot, check if 
28  it is <> Nil. If so, dispose of the memory it points at! }
29      if p <> nil then
30        Dispose(p);
31      { store the passed pointer into the slot }
32      Items[index] := Ptr;
33    end;
34  end;
36  function TRecordList.GetRecord(index: Integer): PRecord;
37  begin
38    { return the pointer in slot index, typecast to PRecord }
39    Result := PRecord(Items[index]);
40  end;
42  procedure TRecordList.Clear;
43  var
44    i: Integer;
45    p: PRecord;
46  begin
47    { dispose of the memory pointed to by all pointers in the list that are not Nil }
48    for i := 0 to Pred(Count) do
49    begin
50      p := Records[i];
51      if p <> nil then
52        Dispose(p);
53    end;
54    { call the Clear method inherited from TList to set Count to 0 }
55    inherited Clear;
56  end;
58  destructor TRecordList.Destroy;
59  begin
60    { clear the list to dispose of any pointers still stored first }
61    Clear;
62    inherited Destroy;
63  end;

All we did up to here was declaring types, lets put them to use now. First we need 
an instance of TRecordList to store pointers to dynamically allocated records in. 
That may be a field in a form, for example. Code to create and destroy the list has 
to be added to the forms OnCreate and OnDestroy handlers.

64  { in a forms public section: }
65  RecordList: TRecordList;
67  { in the forms OnCreate handler }
68  RecordList := TRecordList.Create;
70  { in the forms OnDestroy handler }
71  RecordList.Free;
74  //To add a record to the list you use code like this:
77  var
78    Ptr: PRecord; { local variable in a method }
80    New(Ptr); { allocate a record on the heap }
81    with Ptr^ do
82    begin { note the caret to dereference the pointer }
83      { put data into the fields of the record }
84    end;
85    recordIndex := RecordList.Add(Ptr);

You do this sequence for each record you need to store. Each record now resides at a specific slot in the list and you can access it via the index of this slot. Indices start at 0 and run to RecordList.Count-1.

Vote: How useful do you find this Article/Tip?
Bad Excellent
1 2 3 4 5 6 7 8 9 10


Share this page
Download from Google

Copyright © Mendozi Enterprises LLC