Dismiss Notice

REGISTRATION IS AFTER ADMIN ACTIVATION

DONATIONS WITH PAYPAL CLICK TO BUTTON

1 MONTH VIP - 5$; 3 MONTHS VIP - 10$; 6 MONTHS VIP - 20$; 1 YEAR VIP - 30$; 2 YEARS VIP - 50$; GOLD USER FOR LIFE VIP - 150$

DONATIONS WITH Bitcoin Address:3NRs3CK3fhXifrNYxHEZKpETDd9vNLMsMD

Dismiss Notice
The registration is approved by the Administrator. It takes about 1 day to approve your registration
Dismiss Notice
For open hidden message no need write thanks, thank etc. Enough is click to like button on right side of thread.

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

Discussion in 'Delphi Programming' started by AdminDF, Feb 1, 2014.

  1. AdminDF
    Online

    AdminDFAdminDF is a Verified Member DelphiFan Administrator Staff Member DF Staff

    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]Problem/Question/Abstract:[/font]

    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]How to store records in a TList when their number is unknown until runtime[/font]

    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]Answer:[/font]

    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]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.[/font]


    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]type[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  TRecord = record { the record type }[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]    { ... }[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  end;[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  PRecord = ^TRecord; { pointer type for pointers to TRecords }[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  TRecordList = class(TList) { a customized version of TList to hold PRecord pointers }[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  private[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]    procedure SetRecord(index: Integer; Ptr: PRecord);[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]    function GetRecord(index: Integer): PRecord;[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  public[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]    procedure Clear;[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]    destructor Destroy; override;[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]    property Records[i: Integer]: PRecord read GetRecord write SetRecord;[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  end;[/font]

    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  {Methods of TRecordList}[/font]

    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]procedure TRecordList.SetRecord(index: Integer; Ptr: PRecord);[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]var[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  p: PRecord;[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]begin[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  { get the pointer currently in slot index }[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  p := Records[index];[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  if p <> Ptr then[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  begin[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]    { if it is different from the one we are asked to put into this slot, check if it is <> Nil. If so, dispose of the memory it points at! }[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]    if p <> nil then[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]      Dispose(p);[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]    { store the passed pointer into the slot }[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]    Items[index] := Ptr;[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  end;[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]end;[/font]

    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]function TRecordList.GetRecord(index: Integer): PRecord;[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]begin[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  { return the pointer in slot index, typecast to PRecord }[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  Result := PRecord(Items[index]);[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]end;[/font]

    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]procedure TRecordList.Clear;[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]var[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  i: Integer;[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  p: PRecord;[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]begin[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  { dispose of the memory pointed to by all pointers in the list that are not Nil }[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  for i := 0 to Pred(Count) do[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  begin[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]    p := Records;[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]    if p <> nil then[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]      Dispose(p);[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  end;[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  { call the Clear method inherited from TList to set Count to 0 }[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  inherited Clear;[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]end;[/font]

    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]destructor TRecordList.Destroy;[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]begin[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  { clear the list to dispose of any pointers still stored first }[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  Clear;[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  inherited Destroy;[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]end;[/font]



    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]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.[/font]


    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]{ in a forms public section: }[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]RecordList: TRecordList;[/font]

    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]{ in the forms OnCreate handler }[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]RecordList := TRecordList.Create;[/font]

    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]{ in the forms OnDestroy handler }[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]RecordList.Free;[/font]


    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]To add a record to the list you use code like this:[/font]


    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]var[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  Ptr: PRecord; { local variable in a method }[/font]

    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  New(Ptr); { allocate a record on the heap }[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  with Ptr^ do[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  begin { note the caret to dereference the pointer }[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]    { put data into the fields of the record }[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  end;[/font]
    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]  recordIndex := RecordList.Add(Ptr);[/font]


    [font=Arial, Tahoma, Helvetica, FreeSans, sans-serif]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.[/font]
     

Share This Page

Laws
Our website, law, laws, copyright and aims to be respectful of individual rights. Our site, as defined in the law of 5651 serves as a provider of space. According to the law, contrary to the law of site management has no obligation to monitor content. Therefore, our site has adopted the principle of fit and remove. Works are subject to copyright laws and is shared in a manner that violated their legal rights, or professional associations, rights holders who, adsdelphi@gmail.com I can reach us at e-mail address. Complaints considered to be infringing on the examination of the content will be removed from our site.
Donate Help To Us and Be VIP
DONATIONS WITH PAYPAL CLICK TO BUTTON
6 MONTHS VIP - 20$; 1 YEAR VIP - 30$; 2 YEARS VIP - 50$; GOLD USER FOR LIFE VIP - 150$
Social Block