Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Visual C++/MFC/WTL > Ошибка Access violation. Что делать? |
Автор: Avenger2k 23.5.2006, 23:17 | ||||||
При выполнении программы в этом участке кода:
вылетает такая ошибка Unhandled exception at 0x0040622e in Demo4_debug.exe: 0xC0000005: Access violation reading location 0x000052b7. Вылетает именно на строчке
т.е. что-то не так с массивом. НО, такие же инструкции есть практически во всем коде и везде все работает нормально. Все процедуры и функции отрабатывают на ура, но вот стоило добавить еще одну функцию, работающую с этим массивом и на тебе ![]() вот пример других циклов, которые никаких ошибок не вызывают:
В дебаге сижу уже вторые сутки и ничего не могу добиться. Мочему-то массив получается не инициализированным именно в этой функции, хотя перед ее вызовом идет явная инициализация всех данных массива, его полное заполнене и еще вызывается несколько функций, которые с этим массивом работают! ![]() Кто-нибудь сталкивался с такими чудесами или может есть дельные мысли? Коллеги, нужна Ваша помощь! ![]() |
Автор: DeadSoul 23.5.2006, 23:42 |
Скорее всего этот mField указатель указывает куда-то не туда |
Автор: Avenger2k 24.5.2006, 00:48 |
mField - это не указатель, а статический массив ![]() |
Автор: Kostt 24.5.2006, 07:00 |
думаю dx, dy или count вылазят за границы массива, либо он не инициализирован во время вызова функции |
Автор: skyboy 24.5.2006, 08:29 |
А почему это сразу обращение "за пределы" должно происходить в той же строке, где происходит сбой? Кто-то до этого(может, намного раньше) тихонько потёр память и сказал : "это моё", а сбой произошёл только тогда, как твой статистический массив пришёл и начал качать права: "это моё место!".. Вот и возник Access violation. А бага почти наверняка - при работе с указателями либо использовались неинициализированные указатели, не равные nil, либо был выход за пределы массива в динамическом массив(уж не знаю, как эта штука выглядит в С++).. |
Автор: Earnest 24.5.2006, 09:27 | ||
Нет,
|
Автор: Avenger2k 24.5.2006, 13:21 | ||
Обращение "за пределы" происходит именно в этой строке. В отладчике если проверять работу кода по строчкам, то при переходе отладчика на эту строку и попытке ее выполнить прога вылетает. dx, dy не вылезают за пределы. Вот кусок кода чуть повыше проблемной строки:
раньше dx, dy вообще не было, но я уже не знаю как изъ@%нуться, чтобы все заработало. Раньше было так: if (mField[x - i][y - j].Occupied == mColor) Таким образом у нас dx, dy всегда больше или равно нулю. В других циклах, если к "x" и "y" прибавляется значение таким же образом проверяется, чтобы dx, dy были меньше размерности массива. "x", "y" задаются как параметры для функции. Я для отладки спецом выбрал их значения в середине массива, чтобы любые неучтенные вычисления не вышли за пределы, но ошибка все равно вылетает. Вечером сегодня посмотрю где находится 0x000052b. Самое ужасное, что меня выводит больше всего из рабочего состояния - это то, что таких проверок по всему коду разбросано как будто колхозник прошел и как пшеницу их сеял (т.е. ОЧЕНЬ много) и везде все работает окромя этой злосчастной функции ![]() |
Автор: skyboy 24.5.2006, 14:37 |
У меня указатель Ptr: Pointer; В нём хранятся данные. В смысле, там указатель на реальные данные, а не на мусор. Перед ним объявлена строка Str:strin[6]. В строке 6 символов. Я записываю седьмой: Str[7]='F'. Он затирает старое значение указателя. Вопрос такой: когда у меня произойдёт сбой? Разве по факту записи в "не свою" ячейку? Или может, всё-таки, тогда,когда я попытаюсь работать с Ptr как с ссылкой на Tbutton? А если сбой произойдёт только при обращении, значит ли это, что ошибка у меня в обращении к объекту или, может, мне бы поискать ту самую строку Str[7]:='F', которая находится на 2 страницы ранее по листингу? |
Автор: Earnest 24.5.2006, 16:06 |
Да, верно, если dx, dy правильные, проверь значение указателя mField. И не говори, что это не указатель. Адрес-то все равно есть. Странно, конечно, если mField - статическая переменная, но чего только не бывает... Попробуй сделать полный ребилд всего приложения. Иногда бывают глюки с не-отслеживанием зависимостей. Если ничего не получится, начинай комментировать код вокруг (в основном, до), попробуй добиться, чтобы работало нормально. Я понимаю, что предыдущий код зачем-то нужен, но замени его какими-нибудь стабами. Потом смотри, что приводит к ошибке. Добавлено @ 16:07 Кстати, проверь еще, может это mColor испорчен, а не mField... |
Автор: Avenger2k 24.5.2006, 16:13 | ||||
![]() Перед тем, как производить какие-то действия с массивом в этой функции я считываю одно значение массива и записываю ее в переменную
затем я объявляю еще один одномерный массив (локальный) и в цикле заполняю его данными
Так вот перед тем, как заполнить новый массив mField указывает на один адрес памяти, а после заполнения mCollapse - уже на другой. В следствии чего возникает ошибка. Может кто-нибудь объяснить как заполнение одного локального массива данными может повлиять на то, куда указывает указатель на другой массив объявленный как глобальная переменная? Чет это у меня в голове не укладывается ![]() Спасибо всем, кто откликнулся на мою просьбу о помощи. Выяснив причину теперь надо понять как такое могло произойти ![]() P.S. skyboy, это ты к чему? |
Автор: skyboy 24.5.2006, 16:18 |
в приведённом тобою коде все нормально с индексами? там точно 18 элементов - в массиве mCollapse? |
Автор: Avenger2k 24.5.2006, 19:00 | ||||
... Collapse mCollapse[17]; ...
|
Автор: skyboy 24.5.2006, 20:06 |
Ты объявил массив из 17 элементов?А пытаешься обработать 18? Я тебя правильно понял? ![]() |
Автор: Avenger2k 24.5.2006, 21:59 |
В С/С++ все начинается с нуля, т.е. объявляя 17 элементов у нас получится 0,1,2,3...17, итого 18 обрабатывается for (i=0;i<18;i++) - от 0 до 17 |
Автор: skyboy 24.5.2006, 22:11 |
Avenger2k, с нуля начинается адресация при доступе. Ты же объявил массив на 17 элементов, а пытаешься получить доступ к 18... Ведь если Collapse mCollapse[17]; - это 18 элементов, тогда Collapse mCollapse[0]; - это 1 элемент резервируется?! А как тогда объявить массив из 0 элементов? Collapse mCollapse[-1]?! Как это? |
Автор: Avenger2k 24.5.2006, 22:34 |
skyboy, хмм, кажись ты прав. Это у меня уже крышу срывает. По QuikWatch в дебаге глянул - заканчивается массив на mCollapse[16]. Главное прога все это дело проглатывает без малейшего возмущения. Временно объявил этот массив глобально и так же с ним работал (for (i=0;i<18;i++) ) и никаких ошибок это не вызывало нигде, даже в описанной выше функции. Это баг или фича? (С) неизвестный издатель ![]() Всем спасибо, во всем разобрался. ![]() |
Автор: skyboy 24.5.2006, 22:49 |
Avenger2k, это фича. Раз работа с указателями(чем и является работа с массивами) - то работа с указателями. Без никаких ограничений на использование индекса - вдруг ты хочешь получить доступ "не к своим" данным, но в виде массива? |
Автор: Avenger2k 25.5.2006, 19:06 |
Thx ![]() |