Место записи нарушения доступа 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.

Попробуйте выяснить, не пытаетесь ли вы вызвать то, что не существует.