Место записи нарушения доступа 0xcccccccc
За последние 2 дня я застрял в нарушении, которое, похоже, не может исчезнуть.
Я использовал точки останова и обнаружил, где ошибка, но я просто надеюсь, что один из вас узнает, что проблема без меня, чтобы скопировать + вставить весь мой код -.-
Я получаю
Исключение первого шанса в 0x1027cb1a (msvcr100d.dll) в Escape.exe: 0xC0000005: место записи нарушения доступа 0xcccccccc. Необработанное исключение в 0x1027cb1a (msvcr100d.dll) в Escape.exe: 0xC0000005: место записи нарушения доступа 0xcccccccc.
Теперь быстрый поиск в Google заставляет меня думать, что что-то странное происходит. Все результаты поиска говорят о указателях, которые на самом деле не указывают нигде (0xccccccccc - это низкий адрес памяти?).
Мне еще нужно использовать указатели в моем коде, но в любом случае я вставлю эту функцию и укажу строку, которую исключение выбрано (выделено полужирным шрифтом):
void mMap::fillMap(){
for(int i = 0; i <= 9; i++){
for(int z = 0; z <= 19; z++){
Tile t1; // default Tile Type = "NULLTILE"
myMap[i][z] = t1;
}
}
}
Теперь myMap - это 2-й массив типа Tile. Я работал пару дней назад, пока не добавил несколько других классов, и все это перестало работать!
Ответы
Ответ 1
Либо неинициализированный указатель, либо указатель, сохраненный в памяти, которая была освобождена. Я думаю, что cccccccc
является первым, а cdcdcdcd
- вторым, но он отличается от реализации компилятора/библиотеки.
Для вашего конкретного кода, вероятно, myMap
еще не выделен, тогда myMap[0][0]
приведет к попытке доступа к 0xcccccccc
.
Также может случиться так, что myMap
является началом вашего класса, а указатель класса не инициализирован:
class mMap
{
Tile myMap[10][20];
public:
void f() { myMap[0][0] = 0; }
};
mMap* what;
what->f(); // what is an invalid pointer
Это происходит потому, что функция-член не является виртуальной, поэтому компилятор знает, какой код запускать и передает указатель объекта в качестве скрытого параметра. В конце концов компилятор исчисляет так:
this + offsetof(Whatever::myMap) + z * sizeof(myMap[0]) + i * sizeof(myMap[0][0])
this
, будучи неинициализированным, составляет 0xcccccccc
. Очевидно, что часть offsetof
равна нулю, а i
и z
равны нулю в первый раз через ваш цикл, поэтому вы получаете 0xcccccccc + 0 + 0 + 0
в качестве адреса памяти.
Чтобы отладить это, используйте стек вызовов и найдите функцию, которая называется fillMap
. Затем проверьте эту функцию, в которой указатели, используемые для доступа членов (->
), пришли из.
Ответ 2
В MSVС++ и в режиме отладки блок распределения памяти для отладки устанавливает всю возвращенную память в 0xcccccccc, как способ найти случаи поведения undefined. По всей вероятности, вы никогда не инициализировали myMap
или некоторые указатели внутри myMap
. Проверьте код инициализации на наличие ошибок.
Ответ 3
Была такая же ошибка, когда я попытался заполнить строковое значение в элементе таблицы моего типа собственного класса с помощью for-loop. Я объявил 1000 элементов в этой таблице, поэтому я добавил что-то вроде этого:
for (int i = 0; i <= 1000; i++)
{
TAble[i].name = "Some Guy";
TAble[i].age = 4;
}
К сожалению, как и в случае с строкой, я, возможно, настаиваю на том, что элемент fillinf, который не существует, - это номер элемента 1000 в таблице. Мне удалось это решить, изменив заголовок цикла, удалив знак равенства до 1000.
Попробуйте выяснить, не пытаетесь ли вы вызвать то, что не существует.
Ответ 4
Для всех ответов и комментариев, возникающих в этом вопросе, вот хорошие ссылки на заполнение памяти в Visual С++: