0
votes

I have encountered an access violation error [Access violation at address 5005F6E in module 'rtl170'. Read of address 0000000A] using the IInterfaceList. My code looks something like this:

if  not Assigned(FoRoutingCodes) then Exit;
for i := 0 to FoRoutingCodes.nCount - 1 do
begin
  ...
end;

the declaration of FoRoutingCodes is:

FoRoutingCodes : IRoutingCodeList;

and the definition of IRoutingCodeList

IRoutingCodeList = interface
  function GetCount: Integer;
    ...
  property nCount: Integer read GetCount;
end;

the implementation of nCount property is:

function TRoutingCodeList.GetCount: Integer;
begin
  Result := 0;
  if Assigned(FoItems) then
    Result := FoItems.Count; // here i get the access violation error
end;

where TRoutingCodeList is the implementation of IRoutingCodeList and FoItems is declared as:

FoItems: IInterfaceList;

I have fixed this using

FoItems: TList<IRoutingCode>;

instead of

FoItems: IInterfaceList;

I am new to delphi, can anyone help me understand what was wrong with previous approach. I don't know if this is relevant because there are many other changes is our product, but this issue appeared only after we moved from Delphi XE to Delphi XE3.

Thanks in advance.

Update: in response to Uwe Raabe

I have changed FoItems initialisation from

constructor TRoutingCodeList.Create;
begin
  FoItems := TInterfaceList.Create;
end;

to

constructor TRoutingCodeList.Create;
begin
  FoItems := TList<IRoutingCode>.Create;
end;
1
you have a nil dereference. you almost certainly try to do something like x := TSomeClass(nil).SomeMember. Think which pointer passed to RTL could be zeroArioch 'The
I don't cast back from the interface to some class nowhere in my code... or maybe I misunderstood what you're trying to say?LZR
Interfaced objects in Delphi implement a specific memory model of Automatic Reference Counting. You have to accommodate for this in a special way, which may be implemented or not implemented in "TList<T>". Set some logging in object destructors and most probably you would see objects unexpectedly destroyed in the moment you pass them to the list or soon after. Base your list on a specific interface-aware list docwiki.embarcadero.com/Libraries/XE3/en/…Arioch 'The
Can you show how you initialize FoItems either way?Uwe Raabe
@pavel.lazar then as i said use debug DCUs and intercept what triggered the destructorArioch 'The

1 Answers

0
votes

Considering only the code you posted so far, I can´t see the problem. However, since you know the exact location of the error, my advice is to set a breakpoint at that line in code and evaluate (CTRL+F7) the member FoItems to see what is it.

Usually, when I suspect I have a bad object reference, I evalute it´s ClassName (in your case, FoItems.ClassName). If the reference is invalid, this method usually raises an exception of returns a strange name.

Also, set a breakpoint in the constructor in order to be sure that FoItems is indeed being instantiated.

I Hope this helps!