2013-04-02 70 views
2

我試圖清除一個stringgrid,但我得到一個不一致的訪問衝突消息,似乎在最後一列已被清除後出現。下面是代碼:清理stringgrid時的EAcessViolation

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錯誤消息:\用戶\所有者\ V0.66 \ Project1.exe出現錯誤消息:'訪問
違反0x00401c51:寫入地址0x00316572'。進程已停止。使用步驟或運行
繼續。

錯誤消失時,我的代碼改成這樣:

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的實例?

嘗試使TfrmHighscores的過程ClearTable私人和撥打:

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許多使用的數據看看。
當他有足夠的數據覆蓋,他得到一個堆棧溢出錯誤。