var
i: integer;
aList: TObjectList;
begin
aList := TObjectList.Create;
.........
.........
for i:=0 to aList.Count - 1 do
try
TMyObject(aList[i]).Free;
except on e: exception do
//showmessage('TMyObject(aList[i]).Free exception: ' + e.message);
end;
try
aList.Free;
except on e: exception do
showmessage('aList.Free exception: ' + e.message);
end;
Any idea?
for i:=(aList.Count-1) downTo 0
If you loop upwards, the index will rise and, half-way up, meet the top of
the ObjectList coming down. The barrel will burst, the bricks will fall out
and you will end up with your fingers caught in the pulley...
Rgds,
Martin, (apologies to G. Hoffnung)
- Brian
You're doing something to memory that you're not allowed to do. That's
what an access violation means. Since that's all you've given us, that's
all anyone can conclude.
You are in the unique position of being the one sitting in front of your
computer with the full source code and the debugger at your disposal.
Use them. Step through the program and find out which iteration of the
loop leads to the access violation. If it occurs during the loop, pay
attention to which iteration fails. Is there something special about
that one? (If you skip that iteration, does it fail on the next one
instead?) If the code gets through the loop, then do you get an
exception when you try to free the list? Turn on the "debug DCUs"
compiler option (and rebuild) so you can see where your program really
crashes.
--
Rob
> I got the access violation when I tried to free a TObjectList:
>
> var
> i: integer;
> aList: TObjectList;
> begin
> aList := TObjectList.Create;
> .........
> for i:=0 to aList.Count - 1 do
> try
> TMyObject(aList[i]).Free;
You have created the object list in a way that makes it *own* the
objects you put into it (the constructor has a parameter which
determines that, its default value is true). You do not need to go over
the list and delete the contents, the list object will free the objects
in the list automatically when it is destroyed. And that is the cause
of your problem: you free the objects but do not set the items to nil,
so the list tries to free the objects a second time and that fails with
an AV since the references in the list have been made invalid by you.
--
Peter Below (TeamB)
Don't be a vampire (http://slash7.com/pages/vampires),
use the newsgroup archives :
http://www.tamaracka.com/search.htm
http://groups.google.com
No, that's not it, since merely calling Free doesn't remove an item
from the list (calling Delete on the list itself, in contrast, does).
Peter's identified the reason for the access violation - by default,
TObjectList frees its items in its destructor automatically.
Whether or not it was the problem you are having, it is always advisable to
release items in a list in reverse order anyway.
Woody (TMW)
Why, unless you're actually deleting them too? As in, repeatedly
deleting the first item is of course silly because it causes repeated
copying of the item pointers. If you're not actually changing the list
size though it doesn't matter surely...?
"Chris Rolliston" wrote
> Why, unless you're actually deleting them too?
For several small reasons!
(1) Counting down to zero may result in less code than
counting up.
(2) If you are freeing objects or other memory resources,
it may allow a simple memory manager to better recombine
the memory blocks if done in reverse of the order of
allocation.
(3) If you do accidentally delete the items after freeing the
object or if the deletion of the object automatically deletes
the list reference then you do not have to come back here
and ask why you are having an access violation problem.
HTH, JohnH
At the risk of sounding pedantic (though personally I count down, other
things being equal, for *any* sort of enumeration)...
> (1) Counting down to zero may result in less code than
> counting up.
Code generated do you mean? Perhaps so, but if this is to any degree
significant, surely using TList (or a descendent) in the first place is
significantly sub-optimal, given the way its internal Notify method is
called for every single deletion, addition or extraction.
> (2) If you are freeing objects or other memory resources,
> it may allow a simple memory manager to better recombine
> the memory blocks if done in reverse of the order of
> allocation.
Which depends on how the list was filled in the first place (and
assumes it wasn't then altered in the meantime). Moreover, such a
usage case would again imply not using TList in the first place - you'd
use a dynamic array instead, no?
> (3) If you do accidentally delete the items after freeing the
> object or if the deletion of the object automatically deletes
> the list reference then you do not have to come back here
> and ask why you are having an access violation problem.
Hmm... If I accidentally do something contrary to what I meant to do,
I generally prefer to find out about it as quickly as possible...
Hi Peter,
Now I just called
aList.Free;
and yes there is no AV anymore now.