You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 18:31:02