Ioannis Anifantakis
asked on
Delphi7, "Variable Required" error when accessing address of array element
Hello experts,
I have delphi 7 running and I face a problem with a method I write:
I have created this method:
procedure TCRMEasyListview.getChecke dList(var ListToFill: TList);
var i: integer;
begin
ListToFill.Clear;
with Self.Items do begin
for i:=0 to Count-1 do begin
if Items[i].Checked then
ListToFill.Add(@Items[i]); //<-- "Variable Required" compiler error
end; // end of for loop
end; // end of with declaration
end; // end of method
TList adds pointers. So I try to get the pointer for a pointed item. The pointed item is a TEasyItem (so its an object). Strangely I cannot get the compiler to finish without error.
Any suggestions plz?
I have delphi 7 running and I face a problem with a method I write:
I have created this method:
procedure TCRMEasyListview.getChecke
var i: integer;
begin
ListToFill.Clear;
with Self.Items do begin
for i:=0 to Count-1 do begin
if Items[i].Checked then
ListToFill.Add(@Items[i]);
end; // end of for loop
end; // end of with declaration
end; // end of method
TList adds pointers. So I try to get the pointer for a pointed item. The pointed item is a TEasyItem (so its an object). Strangely I cannot get the compiler to finish without error.
Any suggestions plz?
>>ListToFill.Add(@Items[i] ); // i think @ is the problem.Remove @ and try
procedure TCRMEasyListview.getChecke dList(var ListToFill: TList);
var i: integer;
begin
ListToFill.Clear;
with Self.Items do begin
for i:=0 to Count-1 do begin
if Items[i].Checked then
//ListToFill.Add(@Items[i] ); //<-- "Variable Required" compiler error
ListToFill.Add(Items[i]); //<--
end; // end of for loop
end; // end of with declaration
end; // end of method
procedure TCRMEasyListview.getChecke
var i: integer;
begin
ListToFill.Clear;
with Self.Items do begin
for i:=0 to Count-1 do begin
if Items[i].Checked then
//ListToFill.Add(@Items[i]
ListToFill.Add(Items[i]); //<--
end; // end of for loop
end; // end of with declaration
end; // end of method
ASKER
Thank you both for your answers
Giving directly the item gives error when trying to retrieve that. You need to assign pointer to item and not item itself...
a) mokule:
Since I declare ea, I can assign it by "mylist.add(@ea)" and not ea directly for the reason I explained above. But that gives me a question...
Doesn't declaration of ea give me memory leak? When I declare ea and then assign as value the value held by the array item, I infact clone the array item to the ea variable. That would give me memory leak. If on the other hand I call "free" after i "add" my ea then the list will hold a nil.
So:
ea:=items[i];
mylist.add(ea); -> will compile but will give runtime error since ea is object and not pointer.
(This is similar approach to expert dinlud so, sorry it won't work)
------------------------
ea:=items[i];
mylist.add(@ea); -> correct but with memory leak
-------------
ea:=items[i];
mylist.add(@ea);
ea.free; --> Since mylist holds reference to ea object since I free it here, it wil have problem by the method that calls this code.
Giving directly the item gives error when trying to retrieve that. You need to assign pointer to item and not item itself...
a) mokule:
Since I declare ea, I can assign it by "mylist.add(@ea)" and not ea directly for the reason I explained above. But that gives me a question...
Doesn't declaration of ea give me memory leak? When I declare ea and then assign as value the value held by the array item, I infact clone the array item to the ea variable. That would give me memory leak. If on the other hand I call "free" after i "add" my ea then the list will hold a nil.
So:
ea:=items[i];
mylist.add(ea); -> will compile but will give runtime error since ea is object and not pointer.
(This is similar approach to expert dinlud so, sorry it won't work)
------------------------
ea:=items[i];
mylist.add(@ea); -> correct but with memory leak
-------------
ea:=items[i];
mylist.add(@ea);
ea.free; --> Since mylist holds reference to ea object since I free it here, it wil have problem by the method that calls this code.
ASKER
b) dinilud:
the "@" denotes "The address of". Since I must add pointers to TList, I need it otherwise even though it compiles you get "Access Violation" runtime error.
Therefore its necessary to include either "@" or "Addr" to specify address of object referenced
Quite a wridle this question, ah? :)
the "@" denotes "The address of". Since I must add pointers to TList, I need it otherwise even though it compiles you get "Access Violation" runtime error.
Therefore its necessary to include either "@" or "Addr" to specify address of object referenced
Quite a wridle this question, ah? :)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Mokule is correct. What you don't understand is that ea is also a pointer. Delphi is just hiding that detail from you. The actual object is a bunch of memory allocated on the heap. You don't have to worry about using @ when storing objects in a TList, just dump them in there and use type casting to retrieve them. I do it all the time.
procedure TCRMEasyListview.getChecke
var
i: integer;
ea: TEasyItem;
begin
ListToFill.Clear;
with Self.Items do begin
for i:=0 to Count-1 do begin
if Items[i].Checked then
begin
ea := Items[i];
ListToFill.Add(ea); //<-- "Variable Required" compiler error
end;
end; // end of for loop
end; // end of with declaration
end; // end of method