0
votes

I'm tidying up some code I've been given, for some reason, if the variables are defined under 'Private' (where they need to be to constrain access within this unit). I get EAccessViolation error when writing to them. If I loosely define them under Var just before implementaion they can be accessed ok. I'm comparing my structure with other similar units, where the Private units work fine & cant spot any significant differences.. Any suggestions?

Error MSG: Project --- raised exception class EAccessViolation Error with message 'access vilation error in module----. Read of address 0000050F

interface
uses
  dialogs, math, dateutils, SysUtils, classes;
type
     //double = extended;   
     TDoubleDoubleArray = array of array of double;
     TSunPositionAlgorithm = class (TObject)
         private
           FLocationChanged: boolean;
         public
           Constructor Create;
           Destructor Destroy;
           procedure SetDefaults;
         end;
  Var
    SunPositionAlgorithm : TSunPositionAlgorithm;
           F_L0: Double;
           F_L1: TDoubleDoubleArray;

implementation
  {TSunPositionAlgorithm }

constructor TSunPositionAlgorithm.Create;
begin
  SetDefaults;
end;

procedure TSunPositionAlgorithm.SetDefaults;
Begin
F_L0:= 1;                   // works ok
  FLocationChanged:=true;  // throws eaccess violation error
End;

Calling function (added to Post after David H's 1st question):

  procedure TSun.NRELPositionOfSun(const DateTime: TDateTime; var Azimuth, Elevation, Declination: double);
  Var

    LSunPositionAlgorithm : TSunPositionAlgorithm;
  Begin
    LSunPositionAlgorithm := TSunPositionAlgorithm.Create;
    Try
      LSunPositionAlgorithm.SetDefaults;

  blah..


    Finally
      LSunPositionAlgorithm.Destroy;
    End;
  End;
1

1 Answers

4
votes

You haven't shown the code that calls this code. However, it's pretty obvious that you don't have a valid TSunPositionAlgorithm object.

Get one of those like this:

procedure Test;
var
  spa: TSunPositionAlgorithm;
begin
  spa := TSunPositionAlgorithm.Create;
  try
    spa.SetDefaults;
  finally
    spa.Free;
  end;
end;

You probably have code like this:

procedure Test;
var
  spa: TSunPositionAlgorithm;
begin
  spa.SetDefaults;//oops, spa has not been initialised yet  
end;

or possibly like this:

procedure Test;
var
  spa: TSunPositionAlgorithm;
begin
  spa.Create;//oops, spa has not been initialised yet  
end;

Update You've now shown the calling code but you clearly haven't shown it all, because the code in the question does not exhibit the behaviour you describe. The point I make remains, you must have an invalid object reference somewhere. I've shown a couple of the most common ways for that to come about. But there are other ways to get an invalid object reference.


The other thing wrong with the code in the question is your destructor. They must always be marked with the override directive.

destructor Destroy; override;

You have to do this in order for your destructor to be called when an object is freed.