2013-04-02 7 views
2

Я пытаюсь очистить stringgrid, но я получаю противоречивое сообщение о нарушении прав доступа, которое, кажется, появляется после удаления последнего столбца. Вот код:EAcessViolation при очистке 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; 

Сообщение об ошибке при попытке запустить это

проекта C: \ Users \ Владелец \ V0.66 \ Project1.exe с ошибкой с сообщением: 'доступ
нарушение на 0x00401c51: адрес записи 0x00316572'. Процесс остановлен. Используйте Step или Run
для продолжения.

ошибка уходит, когда я изменить код для этого:

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; 

ответ

0

frmHighscores является экземпляром TfrmHighscores?

попытаться сделать процедуру ClearTable Частного TfrmHighscores и называют:

HighscoreTable.Cols[i].Clear; 

вместо

frmHighscores.HighscoreTable.Cols[i].Clear; 

или вы можете попробовать передавая ссылку на форму в порядке:

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

называя это кодом:

ClearTable(Self); 
4

Это часто происходит из-за неправильных размеров размещения (массив). Последний процесс записи переопределяет границы массива. Это не всегда приводит к ошибке. Но, более или менее важные данные будут перезаписаны.

Предположим, что количество записей составляет 15., а затем Размер файла (Highscorefile) == 15. Массив должен быть [0 .. .14]. Но вы генерируете только длину 14!

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

Так массив [0..13] Последнее задание перезаписывает данные.

В основном за массивом все еще имеется место и не заметит.

Если части TSrings перезаписаны, и вы попытаетесь освободить (с strdispose) перезаписанные данные, тогда есть ошибка.

Если новый код написан,

showmessage('Attempting to clear Col ' +inttostr(i));

Память будет новым организован с перекомпиляцией, а затем эта ошибка возникает в другом месте или не на всех.

Так заменить
SetLength(SortedScores, Filesize(Highscorefile)-1);
с
SetLength(SortedScores, Filesize(Highscorefile));

И пропадет ошибка.

взглянуть на мой ответ https://stackoverflow.com/a/11888156/1322642

OPhow to get two different file with this procedure in deplhi
overwritting многие из используемых данных.
И когда у него достаточно данных, они получают ошибку переполнения стека.