$ 7C81EB33的首次机会异常

时间:2011-04-11 08:03:26

标签: delphi exception

我有一个应用程序,当在家里运行时工作正常,但是当在学校计算机(Windows XP)上运行时,我收到以下消息。 (这是重新编译它,而不仅仅是运行.exe) - 在Delphi 2005中

  

$ 7C81EB33的首次机会异常。异常类EAccessViolation,消息'模块'Project2.exe'中地址0045E5E2的访问冲突。读取地址00000198'。处理Project2.exe(440)

代码:忽略不需要的东西。

        Image1: TImage; // Image(all the way to 72) 
        Timer1: TTimer; Timer2: TTimer;   
        procedure Button1Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure SomeOtherProcedure(Sender: TImage);
        procedure Timer1Timer(Sender: TObject);
        procedure Timer2Timer(Sender: TObject);
          private
        { private declarations }
      public
        { public declarations }
      end;
    var
      Form1: TForm1;
      left : integer;
      top  : integer;
      gap  : integer;
      type
        coordinates = record
          row : integer ;
          col : integer;
        end;

      var
      picarray : array[0..5,0..5] of timage;
      thiscover, midcover, lastcover : timage;
      imageindex : array[0..5,0..5] of integer;
      picloc: array[0..3] of coordinates;
      clickcount, pairsfound, attemptcount : integer;
implementation
{$R *.lfm}
procedure initialise();
var
i, j, whichcol, whichrow : integer;
begin
        for i := 0 to 5 do
        for j := 0 to 5 do
        imageindex[i,j] := -1; // not used
        randomize;
        for i := 0 to 11 do
        for j := 1 to 3 do
        begin
        repeat
          begin
          whichcol := random(6) ;
          whichrow := random(6)  ;
          end;
        until imageindex[whichcol, whichrow] = -1;
        picarray[whichcol, whichrow].Picture.LoadFromFile('C:\Users\Hayden\Pictures\'+ inttostr(I+1) +'.jpg');
        imageindex[whichcol, whichrow] := I  ;
        end;
        clickcount := 0  ;            //
        pairsfound := 0    ;
        attemptcount := 0  ;
        end;

    procedure TForm1.FormCreate(Sender: TObject);
var
cpic : tcomponent;
whichcol: integer;
whichrow : integer;
begin
gap := image2.left - image1.left;
top := image1.Top;
left := image1.left;
for cpic in form1 do
begin
     if (cpic.ClassType = timage) and (cpic.Tag = 10) then
     begin
     whichcol := (timage(cpic).left - left) div gap;
     whichrow := (timage(cpic).Top - top) div gap;
     picarray[whichcol, whichrow] := timage(cpic)   ;
end;
end;
initialise;
end;

行>>> picarray [whichcol,whichrow] .Picture.LoadFromFile('C:\ Users \ Hayden \ Pictures \'+ inttostr(I + 1)+'。jpg'); 似乎导致错误。如果是编码错误,那么正确的方法是什么?

3 个答案:

答案 0 :(得分:3)

首先,我要稍微清理你的代码,因为就目前来说,很难弄清楚发生了什么。我强烈建议您养成花几分钟时间来保持代码清晰格式的习惯 - 这样可以节省数小时的调试时间。

我只应用了以下简单的更改:缩进,空行和begin .. end;

的自由使用
var
  picarray : array[0..5,0..5] of timage;
  thiscover, midcover, lastcover : timage;
  imageindex : array[0..5,0..5] of integer;
  picloc: array[0..3] of coordinates;
  clickcount, pairsfound, attemptcount : integer;

implementation

{$R *.lfm}
procedure initialise();
var
  i, j, whichcol, whichrow : integer;
begin
  for i := 0 to 5 do
  begin
    for j := 0 to 5 do
    begin
      //It's clear you're initialising the 36 entries of imageindex to -1
      imageindex[i,j] := -1; // not used
    end;
  end;

  randomize;
  for i := 0 to 11 do
  begin
    for j := 1 to 3 do
    begin
      //This loop also runs 36 times, so it fills the whole of imageindex with new values
      //It also loads all 36 entries of picarray with an image specfied by the current value of i
      //The approach is dangerous because it depends on the 'loop sizes' matching,
      //there are much safer ways of doing this, but it works
      repeat
        begin //This being one of the only 2 begin..end's you provided inside this is routine is pointless because repeat..until implies it.
          whichcol := random(6) ;
          whichrow := random(6)  ;
        end;
      until imageindex[whichcol, whichrow] = -1;

      //This line itself will throw an access violation if picarray[whichcol, whichrow] doesn't 
      //contain a valid TImage instance... we have to check other code to confirm that possibility
      picarray[whichcol, whichrow].Picture.LoadFromFile('C:\Users\Hayden\Pictures\' + inttostr(I+1) + '.jpg');
      imageindex[whichcol, whichrow] := I  ;
    end;
  end;

  clickcount := 0  ;            //
  pairsfound := 0    ;
  attemptcount := 0  ;
end;

转到下一段代码:

procedure TForm1.FormCreate(Sender: TObject);
var
  cpic : tcomponent;
  whichcol: integer;
  whichrow : integer;
begin
  gap := image2.left - image1.left;
  top := image1.Top;
  left := image1.left;
  for cpic in form1 do
  begin
    //This loop attempts to assign existing TImage instances to picarray
    //However, the way you're going about it is extremely dangerous and unreliable.
    //You're trying to use the position of a component on the form to determine its
    //position in the array.
    //There are many things that could go wrong here, but since this seems to be a
    //homework excercise, I'll just point you in the right direction - you need
    //to debug this code.
    if (cpic.ClassType = timage) and (cpic.Tag = 10) then
    begin
      whichcol := (timage(cpic).left - left) div gap;
      whichrow := (timage(cpic).Top - top) div gap;
      picarray[whichcol, whichrow] := timage(cpic)   ;
    end;
  end;

  //Here you call initialise, which as I said before, will
  //cause an Access Violation if picarray is not correctly 'set up'
  //The previous code in this method certainly has a bug which is 
  //preventing one or more picarray entries from being assigned a 
  //valid TImage instance.
  //You could write a simple for I := 0 to 5, for J := 0 to 5 loop
  //here to check each of picarray entries and pinpoint which is 
  //incorrect to aid your debugging of the pevious loop.
  initialise;
end;

答案 1 :(得分:2)

关键部分是picarray的初始化。您不能确定每个数组元素都分配有TImage组件。如果至少有一个图片有错误lefttop,则您对一个元素进行了双重赋值,而另一个图片则为零。这将在您第一次使用时导致访问冲突,例如在picarray[whichcol, whichrow].Picture.LoadFromFile

我建议用每个维度的for循环重新设计picarray初始化。为了得到正确的TImage,我将它们命名为'Image_2_3',并按名称获取循环中的实例。

答案 2 :(得分:1)

您可以检查文件是否存在并尝试捕获异常以显示有意义的消息

try
  if FileExists('C:\Users\Hayden\Pictures\'+ inttostr(I+1) +'.jpg') then
    picarray[whichcol, whichrow].Picture.LoadFromFile('C:\Users\Hayden\Pictures\'+ inttostr(I+1) +'.jpg');
  else 
    ShowMessage("File not found");
except
  on E : Exception do
    ShowMessage(E.ClassName+' error raised, with message : '+E.Message);
end;