I have a trouble initializing dynamic array in a class. Class looks like this:
MyClass = class
private
var
myVar: array of array of real;
public
constructor Create();
procedure MyMethod(i, j: integer);
end;
Now I'm trying to initialize myVar
in MyMethod()
(after Create()
was called).
procedure MyClass.MyMethod(i, j: integer);
begin
SetLength(myVar, i, j);
end;
This raises 'Access violation reading from address'. I made sure the integers passed are valid so that is not the problem.
Note that when I try to do the same with local variable it works without an issue. Thanks for help.
Edit:
Since requested, here is whole code. It is an window app that is supposed to load a matrix from a text file, perform a Gaussian elimination and than save it to a text file. Originally I made the question more generic but my problem is with SaveToFile
function.
Unit1:
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, Unit2;
type
{ TForm1 }
TForm1 = class(TForm)
OpenB: TButton;
SaveB: TButton;
GaussB: TButton;
OpenDialog1: TOpenDialog;
SaveDialog1: TSaveDialog;
procedure FormCreate(Sender: TObject);
procedure OpenBClick(Sender: TObject);
procedure SaveBClick(Sender: TObject);
private
M: TMatrix;
public
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.OpenBClick(Sender: TObject);
var
path: string;
begin
if OpenDialog1.Execute()then
begin
path:= OpenDialog1.FileName;
M.LoadFromFile(path);
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
M.Create();
end;
procedure TForm1.SaveBClick(Sender: TObject);
var
path: string;
begin
if SaveDialog1.Execute then
begin
path:= SaveDialog1.FileName;
M.SaveToFile(path);
end;
end;
end.
Unit2:
unit Unit2;
{$mode ObjFPC}{$H+}
interface
uses
Classes, SysUtils;
type
TMatrix = class
private
var
matrix: array of array of real;
public
constructor Create();
procedure LoadFromFile(path: string);
procedure SaveToFile(path: string);
end;
implementation
constructor TMatrix.Create();
begin
end;
procedure TMatrix.LoadFromFile(path: string);
var
rows, cols, num, i, j: integer;
f: TextFile;
begin
AssignFile(f, path);
reset(f);
read(f, rows);
readln(f, cols);
SetLength(matrix, rows, cols);
try
for i:= 0 to rows - 1 do
begin
for j:= 0 to cols - 1 do
begin
read(f, num);
matrix[i, j]:= num;
end;
readln(f);
end;
except
raise Exception.Create('Matrix size is incorrect or file is corrupted!');
end;
close(f);
end;
procedure TMatrix.SaveToFile(path: string);
var
num: real;
i, j: integer;
f: TextFile;
begin
AssignFile(f, path);
rewrite(f);
for i:= 1 to length(matrix) do
begin
for j:= 1 to length(matrix[0]) do
begin
num:= matrix[i, j];
write(f, FloatToStr(num) + ' ');
end;
writeln(f);
end;
close(f);
end;
end.
Your call to the constructor is
M.Create();
which is wrong.
Try this instead:
M := TMatrix.Create;