问题
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:
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.
来源:https://stackoverflow.com/questions/12422300/eaccessviolation-av-error-using-variables-in-private