Проблема с выделением памяти в Delphi 3 - PullRequest
4 голосов
/ 05 марта 2011

Я, должно быть, упускаю что-то довольно простое? Я пытаюсь создать связанный список в приложении Delphi 3.

Это реализуется через два класса ItemList и Item . ItemList создается при создании формы. Это сохраняется для жизни формы. Каждый Item объект создается по мере необходимости. Форма имеет функцию с именем AddAcc . AddAcc вызывается с помощью события on-change одного из элементов управления формы.

Что происходит во время этого события при изменении:

  1. AddAcc называется
  2. AddAcc создать новый Item object
  3. AccAdd вызывает ItemList.AddItem и передает Item по ссылке
  4. AddItem мест Элемент объект в конце списка

Я протестировал AddItem , и он работает хорошо. Моя проблема в том, что каждый раз, когда вызывается * AddAcc *, он получает одно и то же место в памяти. Я пробовал разные способы создания нового объекта Item . Я использовал New, GetMem (w / FillChar) и создавал локальную переменную типа Item. Все вызовы AddAcc приводят к получению одной и той же ячейки памяти.

Я передал объект Item напрямую (по ссылке) в AddItem и альтернативно передал указатель на объект Item .

Я думал, что ссылка (указатель) на экземпляр объекта Item в связанном списке обеспечит сохранение местоположения элемента в памяти. Однако, похоже, что он собирается после выхода из класса AddAcc .

FUNCTION AddAcc;

Var

     accItem : ptrItem;

BEGIN

    GetMem(accItem, sizeOf(Item));

    FillChar(accItem^, sizeof(Item), 0);

    ItemList.AddItem(accItem^);

End;



Procedure TItemList.AddItem(Var newItem : TAccessoryItem);

begin
   Inc(_count);

   // add first item to the list            
    If (_count = 1) Then 
    begin       

          _fifoHead := @newItem;
          _tail := @newItem;
          newItem.Next   := @_tail;
          newItem.Previous := @_fifoHead;
          exit;

    end;

     _tail^.Next := @newItem;  
     newItem.Previous := _tail^;
     mewItem.Next := @_tail;
     _tail := @newItem;         
end;

Любая помощь очень ценится.

1 Ответ

1 голос
/ 05 марта 2011

Вот как я бы написал связанный список:

type
  PItem = ^TItem;
  TItem = record
    Next: PItem;
    Data: Integer;
  end;

procedure Add(var First: PItem; Data: Integer);
var
  NewItem: PItem;
begin
  New(NewItem);
  NewItem.Next := First;
  NewItem.Data := Data;
  First := NewItem;
end;

...

var
  First: PItem;
begin
  First := nil;
  Add(First, 42);
  //etc.
end;

Когда вам нужно освободить свой список, вы делаете это:

var
  Item: PItem;
begin
  while Assigned(First) do begin
    Item := First;
    First := Item.Next;
    Dispose(Item);
  end;
end;

Я считаю, что этоканонический способ написания кода типа связанного списка в Паскале.

Я специально написал этот код для этого простейшего связанного списка, который только можно представить.Это позволяет вам сосредоточиться на распределении, использовании указателей и т. Д. Похоже, вы уже знаете, как сохранить ссылки в более сложном списке, и поэтому я полагаю, что у вас не возникнет проблем с адаптацией этого стиля кода под ваши нужды.

...