2012-05-07 1 views
12

У меня очень странная проблема с игрой космических захватчиков, над которыми я работаю. В основном я получаю ошибку нарушения доступа:0xC0000005: Место для обнаружения нарушения доступа 0x00000000

Unhandled exception at 0x5edad442 (msvcr100d.dll) in SpaceInvaders.exe: 0xC0000005: Access violation reading location 0x00000000.

, когда я включаю фрагмент кода ниже. визуальная студия ведет меня к «strcmp.asm» при отладке. Обратите внимание, что Im не использует strcmp() в любом из моего кода. Что-то не так с кодом, или это проблема, выходящая за рамки того, что я включил? Спасибо за любую помощь

const char* invarray[] = {"invader0.png", "invader1.png", "invader2.png", "invader3.png", "invader4.png"}; 
int i=0; 
//Creates 55 invaders 
for (int y=0; y<250; y+=50){ 
    for (int x=0; x<550;x+=50){ 
     Invader inv(invarray[y/50], x+50, y+550, 15, 15, 1, false, 250); 
     invaders[i] = inv; 
    } 
} 

Invader конструктор:

Invader::Invader(const char *pic, int x, int y, int w, int h, bool dir, bool des, int point) : MovingObject(pic, x, y, w, h) , direction(dir), destroyed(des), b(0), points(point){}; 

MovingObject Конструктора

MovingObject::MovingObject(const char *pic, int x, int y, int w, int h):picture(pic), positionX(x), positionY(y), width(w), height(h) {}; 
+1

Показать код внутри конструктора Invader –

+1

Сообщение об ошибке указывает на то, что это разыменование нулевого указателя, но я не вижу, где это произойдет в вашем коде. Помимо конструктора Invader, пожалуйста, покажите нам, где и как инициализируется массив захватчиков. Конструктор копирования Invader может быть интересен, если он есть. – Medo42

+0

Я только что обновил OP с помощью конструкторов[email protected], массив invader был просто инициализирован как глобальная переменная: «Invader invaders [55];» – Milk

ответ

10

Эта линия выглядит подозрительно:

invaders[i] = inv; 

Вы никогда не увеличивающиеся i, поэтому вы продолжаете присваивание invaders[0]. Если это просто ошибка, которую вы сделали при уменьшении кода до примера, проверьте, как вы вычисляете i в реальном коде; вы можете превысить размер invaders.

Если вы предлагаете свои комментарии, вы создаете 55 invaders, а затем проверьте, что invaders был правильно инициализирован для обработки этого номера.

+0

Большое спасибо, вот и все: s – Milk

22

"Нарушение прав доступа чтения расположение 0x00000000" означает, что вы derefrencing a pointer, который не был инициализирован и, следовательно, имеет значения мусора. Эти значения для мусора могут быть любыми, но обычно это бывает 0, поэтому вы пытаетесь прочитать с адреса памяти 0x0, который операционная система обнаруживает и мешает вам делать.

Проверьте и убедитесь, что массив invaders[] - это то, что, по вашему мнению, должно быть.

Также, кажется, вы не обновлять i когда-либо - это означает, что вы продолжаете размещая тот же Invader объект в месте 0 из invaders[] на каждой итерации цикла.

0

Проблема, поясняемая в других комментариях, заключается в том, что указатель является разыменованным, не будучи правильно инициализированным. Операционные системы, такие как Linux, сохраняют наименьшие адреса (например, первые 32 МБ: 0x00_0000 -0x200_0000) из виртуального адресного пространства процесса. Это делается потому, что разыменование нулевых неинициализированных указателей является распространенной ошибкой, как в этом случае. Поэтому, когда этот тип ошибки случается, вместо фактического чтения случайной переменной, которая находится на адресе 0x0 (но не адрес памяти, для которого указатель должен был бы использоваться, если он был правильно инициализирован), указатель будет считывать из адреса памяти вне виртуальное адресное пространство процесса. Это вызывает ошибку страницы, что приводит к ошибке сегментации, и сигнал отправляется процессу, чтобы его убить. Вот почему вы получаете ошибку нарушения доступа.