Delphi 3 Memory Allocation Problem
I must be missing something rather easy? I’m trying to create a linked list in a Delphi 3 application.
This is implemented via two classes ItemList and Item. The ItemList is instantiated at form creation. It persists for the life of the form. Each Item object is instantiated as needed. The form has a function called AddAcc. AddAcc is called via the on-change event of one of the form's controls.
What happens during this on-change event:
- AddAcc is called
- AddAcc create a new Item object
- AccAdd calls ItemList.AddItem and passes the Item by reference
- AddItem places Item object at the tail of the list
I’ve tested AddItem and it works well. My problem is that each time *AddAcc*is called it obtains the same memory location. I’ve tried different means of creating a new Item object. I’ve used New, GetMem (w/ FillChar), and instantiating a local variable of type Item. All calls to AddAcc results in the same memory location being obtained.
I’ve passed the Item object directly (by reference) to AddItem and alternatively passed a pointer to the Item object.
I thought that a reference (pointer) to an instance of the Item object within the linked list would ensure the Item's memory location would be maintained. It appears, however, that it is being collected once the AddAcc class is exited.
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;
Any help is greatly appreciated.
Here's how I'd write a linked list:
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;
When you need to deallocate your list you do this:
var
Item: PItem;
begin
while Assigned(First) do begin
Item := First;
First := Item.Next;
Dispose(Item);
end;
end;
It is my belief that this is the canonical way of writing linked list type code in Pascal.
I've intentionally written this code for this simplest linked list imaginable. That allows you to focus on the allocation, use of pointers etc. You appear to already know how to maintain the references in your more complex list and so I believe you will have no trouble adapting this style of code to your needs.
精彩评论