Исключение первого шанса на $ 7C81EB33 - PullRequest
0 голосов
/ 11 апреля 2011

У меня есть приложение, которое при работе дома работает нормально, однако при запуске на школьных компьютерах (Windows XP) я получаю следующее сообщение.(Это перекомпиляция, а не просто запуск .exe) - В Delphi 2005

Исключение из первого шанса за 7C81EB33.Класс исключения EAccessViolation с сообщением «Нарушение прав доступа по адресу 0045E5E2 в модуле« Project2.exe ».Прочитать адрес 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 ]

3 голосов
/ 25 апреля 2011

Во-первых, я собираюсь немного почистить ваш код, потому что в его нынешнем виде очень трудно понять, что происходит. Я настоятельно рекомендую вам привыкнуть тратить несколько минут на то, чтобы ваш код был четко отформатирован - это сэкономит вам часы отладки.

Я применил только следующие простые изменения: отступ, пустые строки и свободное использование 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;
2 голосов
/ 11 апреля 2011

Критическим разделом является инициализация picarray.Вы не можете быть уверены, что каждому элементу массива назначен компонент TImage.Если хотя бы одно изображение имеет неправильный left или top, у вас есть двойное присвоение одному элементу, а другому остается ноль.Это приведет к нарушению доступа при первом использовании, например, в picarray[whichcol, whichrow].Picture.LoadFromFile.

. Я бы порекомендовал изменить дизайн инициализации picarray с помощью циклов for для каждого измерения.Чтобы получить правильный TImage, я бы назвал их «Image_2_3» и получил бы экземпляры в цикле по имени.

1 голос
/ 11 апреля 2011

вы можете проверить, существует ли файл и попытаться перехватить исключение, чтобы отобразить осмысленное сообщение

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...