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