Search code examples
interfacesegmentation-faultfpc

SIGSEGV when using interfaces


Please take a look at the following Free Pascal program.

type
  IMyInterface = interface
  end;

  TMyClass = class(TInterfacedObject, IMyInterface)
  end;

var
  MyInstance: TMyClass;

procedure DoSomething(MyParameter: IMyInterface);
begin
end;

begin
  MyInstance := TMyClass.Create;

  DoSomething(MyInstance);

  MyInstance.Free;
end.

The program crashes during the access to the destructor with a SIGSEGV when started from within the IDE (compiled with debug information). Why? It works when I use TInterfacedObject, TObject, or TMyClass as parameter type. It even works when I use the const keyword for said parameter. Can anyone explain this behavior? With a quick sideways glance to Java I would expect this to work.

Compiled with FreePascalCompiler 2.6.4, executed under Windows 7.


Solution

  • I cannot speak for FPC, but with Delphi it is a bad idea to mix interfaces and objects. In this case you have two solutions:

    1. declare MyInstance as IMyInterface and remove the call to Free.
    2. inherit TMyClass from TInterfacedPersistent.

    To clarify what is actually happening: Creating the TMyClass instance and assigning it to MyInstance will keep the reference count to 0. When you pass it to DoSomething a cast to IMyInterface takes place and the reference counter increases. When DoSomething ends the reference counter decreases to 0 and the instance is freed. The following call to Free will free an already freed instance.