You are not logged in.
I was getting random exceptions from an ilist with objects
The exception is coming from mormot.core.data line 6988 (fInfo.ArrayRtti.ValueFinalize)
procedure TDynArray.ItemMoveTo(index: PtrInt; Dest: pointer);
var
p: pointer;
begin
p := ItemPtr(index);
if (p = nil) or
(Dest = nil) then
exit;
if (fInfo.ArrayRtti <> nil) and
not fNoFinalize then
fInfo.ArrayRtti.ValueFinalize(Dest); // also handle T*ObjArray
MoveFast(p^, Dest^, fInfo.Cache.ItemSize);
FillCharFast(p^, fInfo.Cache.ItemSize, 0);
end;
which is called by same unit, line 6858
function TDynArray.PopHead(var Dest): boolean;
begin
result := GetCount <> 0;
if result then
begin
ItemMoveTo(0, @Dest);
Delete(0);
end;
end;
The problem was that the object variable passed to pophead was not null and before poping the new object ItemMoveTo try to finalize it.
probably adding a Dest:=nil; somewhere before ItemMove in PopHead?
Or, probably adding this requirement (dest must be nil) in Pop's documentation?
Last edited by dcoun (2022-10-09 16:28:54)
Offline
It seems to be a feature to me.
Forcing FillCharFast(Dest^, fInfo.Cache.ItemSize, 0) would leak memory in most use cases.
How to you use PopHead() ?
The Dest variable should indeed be valid (filled with zeros, or containing a valid instance).
Offline
The definition is:
lowr:ilist<TepGenericSlave>;
The creation is:
lowr:=Collections.NewList<TepGenericSlave>;
The pop is used like the following and produces exceptions:
TepGenericSlave=class
....
obj:=TepGenericSlave.create;
...
repeat
...
lowr.Pop(obj,[popFromHead]);
...
until ....;
The pop is used like the following and does not produce exceptions:
TepGenericSlave=class
....
obj:=TepGenericSlave.create;
...
repeat
...
obj:=nil;
lowr.Pop(obj,[popFromHead]);
...
until ....;
Last edited by dcoun (2022-10-09 21:29:18)
Offline
Pop() will extract the instance from the internal array storage.
It won't fill the destination properties, but copy the instance, after having released the existing instance.
I have added a test which shows how memory is managed, and that there is no leak:
https://github.com/synopse/mORMot2/commit/eadf3f20
If you got a GPF it is very likely than your "obj" instance life time was not correct.
Offline
Last commit is perfect. Thank you a lot @ab
Offline