arrays - 设置数组(记录)长度时,Delphi 堆栈溢出和访问冲突错误

标签 arrays delphi stack-overflow

我正忙于构建一个应用程序,在该应用程序中我正在从两个以上的“记录”文件中读取数据。我有一个非常奇怪的错误,它会根据我打开文件的顺序弹出(请参见下面的代码)。

如果我点击按钮1,然后点击按钮2,从而调用“天气数据记录”文件,然后调用“参数记录”文件,一切都很好。如果我以相反的方式执行此操作,则会收到“堆栈溢出”,然后是“0x7c90e898 处的访问冲突:地址写入”错误。当我为 Button1Click 中的数组调用 SetLength 时,会发生这种情况。

天气数据文件大约有550条记录,参数文件大约有45条记录。

任何人都可以看到我的代码有任何明显的错误吗?如果有人想使用它们来测试,我不确定如何附加文件或使它们可用......

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, ExtCtrls, Grids,FileCtrl,Contnrs;

type  
    TWeatherData = record  
    MyDate : TDate;  
    Rainfall : Double;  
    Temperature : Double;  

  end;

  TParameters = record
    Species : string[50];
    ParameterName: string[50];
    ParameterValue : double;
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
Var
  WeatherDataFile : file of TWeatherData;
  j : integer;
  WeatherDataArray : array of TWeatherData;
  MyFileSize : Integer;

begin


  AssignFile(WeatherDataFile,'C:\Test5.cmbwthr') ;
  Reset(WeatherDataFile);
  MyFileSize := FileSize(WeatherDataFile);

  SetLength(WeatherDataArray,MyFileSize);

  j := 0;

  try
   while not Eof(WeatherDataFile) do begin
    j := j + 1;
    Read (WeatherDataFile, WeatherDataArray[j]) ;
   end;
  finally
   CloseFile(WeatherDataFile) ;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  ParametersFile : file of TParameters;
  j : integer;
  CurrentParameters : array of TParameters;
  MyFileSize : Integer;

begin
  AssignFile(ParametersFile,'C:\Test5.cmbpara') ;
  Reset(ParametersFile);

  Reset(ParametersFile);
  MyFileSize := FileSize(ParametersFile);

  SetLength(CurrentParameters,MyFileSize);

  j := 0;

  try
   while not Eof(ParametersFile) do begin
    j := j + 1;
    Read (ParametersFile, CurrentParameters[j]) ;
   end;
  finally
   CloseFile(ParametersFile) ;
  end;
end;

end. 

最佳答案

您可以通过在写入数组之前而不是之后增加索引来写入超出数组末尾的内容。由于您正在写入不属于数组的内存,因此可能会出现许多问题。

AssignFile(ParametersFile, 'C:\Test5.cmbpara');
Reset(ParametersFile);
try // Enter "try" block as soon as the file is opened.
  MyFileSize := FileSize(ParametersFile);
  SetLength(CurrentParameters, MyFileSize);

  j := 0;
  while not Eof(ParametersFile) do begin
    Read(ParametersFile, CurrentParameters[j]);
    Inc(j);
  end;
finally
  CloseFile(ParametersFile);
end;

if j <> MyFileSize then
  raise Exception.CreateFmt('Parameter count mismatch: expected %d but got %d instead.',
    [MyFileSize, j]);

关于arrays - 设置数组(记录)长度时,Delphi 堆栈溢出和访问冲突错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5413918/

相关文章:

java - 将没有任何循环的二维数组的 C++ 递归填充实现转换为 Java?

c++ - 使用 operator new 进行内存分配并使用数据进行初始化

PHP 数组重复值

c++ - 如何将结构数组写入二进制文件并再次读取?

php - 在 php 中如何设置数组的大小?

delphi - 从 InitTable 获取单位名称 - hack System.pas

c# - 属性 setter 中的 StackOverflowException

python - 使用 `nbytes` 广播后,numpy 数组中的 `broadcast_to` 值错误

sql-server - 从数据库读取 NVARCHAR 后,TClientDataset Widestring 字段的大小加倍

Delphi 将我的对象编码为字符串泄漏,但为什么呢?