1

In Unit2 of my program i have the following code:

TValue = Record
  NewValue,
  OldValue,
  SavedValue : Double;
end; 

TData = Class(TObject)
Public
  EconomicGrowth : TValue;
  Inflation : TValue;
  Unemployment : TValue;
  CurrentAccountPosition : TValue;
  AggregateSupply : TValue;
  AggregateDemand : TValue;
  ADGovernmentSpending : TValue;
  ADConsumption : TValue;
  ADInvestment : TValue;
  ADNetExports : TValue;
  OverallTaxation : TValue;
  GovernmentSpending : TValue;
  InterestRates : TValue;
  IncomeTax : TValue;
  Benefits : TValue;
  TrainingEducationSpending : TValue;
End;

I then declare Data : TData in the Var.

when i try to do the following however in Unit1:

  ShowMessage(FloatToStr(Unit2.Data.Inflation.SavedValue));

I get an EAccessViolation message. Is there any way to access the data stored in 'Data' from Unit1 without getting errors?

chendriksen
  • 1,026
  • 6
  • 16
  • 30
  • If this isn't just for purposes of the example, you might want to consider a different name, as TValue is an actual data type used in the Delphi 2010 for extended RTTI. – Mason Wheeler Apr 13 '10 at 15:15

3 Answers3

6

Add Data := TData.Create; to Unit2's initialization section, or change TData to a record instead of an object. There's nothing inherently wrong with accessing Unit2's global objects from Unit1 as long as they're properly initialized.

Zoë Peterson
  • 13,094
  • 2
  • 44
  • 64
1

@Hendriksen123, do you initialize the variable Data before using it? the EAccessViolation is the exception class for invalid memory access errors, and usually occurs when your code tries to access an object that has not created (initialized) or has already been destroyed.

try using Data := TData.Create;

and then you can use the Data var.

RRUZ
  • 134,889
  • 20
  • 356
  • 483
0
unit Unit2;

interface

type
  TValue = Record
    NewValue,
    OldValue,
    SavedValue : Double;
  end;

  TData = Class(TObject)
  Public
    EconomicGrowth : TValue;
    Inflation : TValue;
    Unemployment : TValue;
    CurrentAccountPosition : TValue;
    AggregateSupply : TValue;
    AggregateDemand : TValue;
    ADGovernmentSpending : TValue;
    ADConsumption : TValue;
    ADInvestment : TValue;
    ADNetExports : TValue;
    OverallTaxation : TValue;
    GovernmentSpending : TValue;
    InterestRates : TValue;
    IncomeTax : TValue;
    Benefits : TValue;
    TrainingEducationSpending : TValue;
  End;

procedure InitialiseData (var pData : TData);

implementation

procedure InitialiseData (var pData : TData);
begin
  pData := TData.Create;

  pData.EconomicGrowth.SavedValue := 1.00;

end;

end.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Unit2,
  StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
  vData : TData;
begin
  Unit2.InitialiseData(vData);

  ShowMessage(FloatToStr(vData.EconomicGrowth.SavedValue));

end;

end.

That works

RRUZ
  • 134,889
  • 20
  • 356
  • 483
Forer
  • 1,045
  • 1
  • 9
  • 32
  • 1
    If you're including code in your post indent it all by 4 spaces and it will keep the formatting and add syntax highlighting. – Zoë Peterson Apr 13 '10 at 15:29
  • Just out of curiosity, if one used this code, where should the TData object be freed--Unit1 or Unit2's code? – Al C Apr 13 '10 at 15:55
  • It should be freed where it's created. – Mason Wheeler Apr 13 '10 at 16:07
  • Thanks, Mason ... Tell me if I got this right: for Unit1 to free the TData object, in a different procedure than Button1Click, vData would have to be declared someplace like class level, right? And what would happen if Unit2's InitializeData method didn't declare the TData parameter as a var? – Al C Apr 13 '10 at 16:55