delphi - 清除 stringgrid 时的 EAcessViolation

标签 delphi access-violation stringgrid

我正在尝试清除字符串网格,但收到不一致的访问冲突消息,该消息似乎在清除最后一列后出现。这是代码:

procedure ClearTable;
var
i:integer;
begin
  for i := 0 to 3 do
    begin
      frmHighscores.HighscoreTable.Cols[i].Clear;
    end;
end;

这是调用它的过程:

procedure TfrmHighscores.sortbtnClick(Sender: TObject);
var
SortedScores :array of Thighscore;
i: integer;
Ascending:boolean;
begin
  ClearTable;
  Case sortRGP.ItemIndex of
   0: Ascending := False;
   1: Ascending :=True;
  end;
  AssignFile(HighScoreFile, 'HighScoreFile.DAT');
  Reset(HighScoreFile);
  If Filesize(Highscorefile) <= 1 then
    begin
      showmessage('There arent enough items to sort!');
    end;
  If Filesize(Highscorefile) > 1 then
    begin
      SetLength(SortedScores, Filesize(Highscorefile)-1);
      i:=0;
      While not eof(HighScoreFile) do
        begin
          Read(Highscorefile, Highscore[i+1]);
          sortedScores[i].Name := Highscore[i+1].Name;
          sortedScores[i].Score := Highscore[i+1].Score;
          sortedScores[i].DateSet := Highscore[i+1].DateSet;
          sortedScores[i].Difficulty := Highscore[i+1].Difficulty;
          inc(i);
        end;
    Closefile(highscorefile);
    Quicksort(SortedScores, Low(SortedScores), High(SortedScores)+1, Ascending);
    end;
end;

当我尝试运行它时,错误消息是

Project C:\Users\Owner\V0.66\Project1.exe faulted with message: 'access
violation at 0x00401c51: write of address 0x00316572'. Process Stopped. Use Step or Run
to continue.

当我将代码更改为以下内容时,错误消失了:

procedure ClearTable;
var
i:integer;
begin
  for i := 0 to 3 do
    begin
      showmessage('Attempting to clear Col ' +inttostr(i));
      frmHighscores.HighscoreTable.Cols[i].Clear;
      showmessage('Col ' +inttostr(i) + ' cleared successfully');
    end;
end;

最佳答案

这通常来自不正确的分配大小(数组)。最后的写入过程会覆盖数组的限制。这并不总是立即导致错误。但是,或多或少重要的数据将被覆盖

我们假设记录数为 15。然后 Filesize(Highscorefile) == 15 。该数组应为 [0.. .14]。但你只生成了 14 的长度!

SetLength(SortedScores, Filesize(Highscorefile)-1); == 14.

所以数组是 [0..13] 最后的赋值会覆盖数据。

大多数情况下,在阵列后面仍然有可用空间,并且不会注意到。

如果部分 TSring 被覆盖,并且您尝试释放(使用 strdispose)覆盖的数据,则会出现故障。

如果编写了新代码,

showmessage('尝试清除 Col ' +inttostr(i));

内存将通过重新编译进行新组织,然后此错误出现在其他位置或根本不出现。

所以替换
SetLength(SortedScores, Filesize(Highscorefile)-1);

SetLength(SortedScores, Filesize(Highscorefile));

错误就会消失。

看看我的回答 https://stackoverflow.com/a/11888156/1322642

OP how to get two different file with this procedure in deplhi
覆盖许多使用过的数据。
当他有足够的数据被覆盖时,他会收到堆栈溢出错误。

关于delphi - 清除 stringgrid 时的 EAcessViolation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15766856/

相关文章:

delphi - TEmbeddedWB 中的 Youtube 视频不再工作?

delphi - 不处理鼠标和键盘事件的表单

delphi - 从 Delphi 打开和关闭外部程序

delphi - 隐藏 StringGrid 的焦点矩形 : Delphi

delphi - TStringGrid 列外标签

delphi - 如何在 Delphi 中以编程方式创建带有几个组件的表单

android - 使用硬件加速 Android MediaCodec 解码器的 native 代码中的访问冲突

java - 在 64-Win 7 上的 32 位 JVM 中读取 C++ 中的 JNI-ByteBuffer 时发生访问冲突

C++ GetModuleFileName 访问冲突

delphi - 如何更改 Delphi Firemonkey XE7 中 Stringgrid 标题的字体大小?