Pascal类中动态数组初始化遇Access violation问题求助
Pascal类动态数组访问违规问题排查与修复
问题描述
在Pascal类中初始化动态数组时触发Access violation reading from address错误。类定义包含私有二维动态数组,在调用Create后的方法中用SetLength初始化该数组时出错,已确认传入的整数参数有效,且局部变量执行相同操作无问题。这是一个用于从文本文件加载矩阵、执行高斯消元并保存的窗口应用,实际错误出在SaveToFile函数中。
原始代码
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.
问题根源
- 对象实例化错误:Unit1中
FormCreate方法未正确实例化TMatrix对象,原代码M.Create();仅调用构造函数但未将返回的对象引用赋值给M,导致M仍是未初始化的空指针,调用其方法时会触发访问违规。正确写法应为M := TMatrix.Create(); - 数组索引越界:Unit2中
SaveToFile方法使用1起始索引访问0基动态数组。Pascal动态数组默认从0开始索引,循环从1到Length(matrix)会超出数组边界,导致访问违规。需将循环改为i从0到Length(matrix)-1,j从0到Length(matrix[0])-1
修复后的关键代码片段
Unit1中修复后的FormCreate方法
procedure TForm1.FormCreate(Sender: TObject); begin M := TMatrix.Create(); end;
Unit2中修复后的SaveToFile方法
procedure TMatrix.SaveToFile(path: string); var num: real; i, j: integer; f: TextFile; begin AssignFile(f, path); rewrite(f); for i:= 0 to Length(matrix) - 1 do begin for j:= 0 to Length(matrix[0]) - 1 do begin num:= matrix[i, j]; write(f, FloatToStr(num) + ' '); end; writeln(f); end; close(f); end;
内容的提问来源于stack exchange,提问作者Matěj Vondráček
相关产品推荐
相关产品推荐

