Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > Очистка мусора с дебаггером и без него


Автор: Nuzur 15.1.2007, 17:41
Суть проблемы заключается  в том, что при дебаге(F5) у меня мусор уберается просто идеальном, а вот при запущеном приложении(CTRL + F5) падает из-за невалидности указателей. Я понимаю что звучит странно но  я незнаю как спросить иначе.

Структура имеет вид:

Код

struct Color
{
public:
    CString Red, Green, Blue;
    CString Channel;
};
typedef Color * ColorPtr;
typedef CSimpleArray<ColorPtr> ColorArray;
typedef ColorArray * ColorArrayPtr;
typedef CSimpleMap<CString, ColorArrayPtr> CmapIdColor;

CmapIdColor mapIdColor;


убираю мусор:
Код

    int i,j,k;
    for(i = 0; i < mapIdColorRTU.GetSize(); i++)
    {
        for(j = 0; j < mapIdColorRTU.GetValueAt(i)->GetSize(); j++)
            for(k = 0; k < mapIdColorRTU.GetValueAt(i)[j].GetSize(); k++)
            {
                delete (ColorPtr)mapIdColorRTU.GetValueAt(i)[j][k]; // здеся вот валиться :(
            }

        mapIdColorRTU.GetValueAt(i)->RemoveAll();
        delete mapIdColorRTU.GetValueAt(i);
    }

Автор: Earnest 15.1.2007, 18:47
Скорее всего в этих указателях что-то нехорошее (неинициализированы). При дебаге вполне там могут быть нули. Так что смотри там, где инициализируешь указатели на Color. Например, если ты увеличиваешь размер массива указателей, но не инициализируешь все новые значения, там вполне может быть грязь. Что-то вроде этого.


Автор: Nuzur 15.1.2007, 18:59
Earnest, Нет все указатели инициализированны, я смотрю дебагом в значения что по них лежат, там все правельно.
Очистку провожу в деструкторе ксатити, екзеплер переменной лежит в MainFrame в разделе private.

Автор: Earnest 15.1.2007, 19:03
Но ведь релиз говорит тебе, что указатель невалидный...
Попробуй распечатывать значения перед удалением и ищи где лажа...

Автор: Nuzur 16.1.2007, 10:30
Earnest, да мне не релиз а дебаг версия говорит что лажа. А что печатать? Сам указатель? Ну и понту мне с него, тоесть с адреса его, тоесть с адреса на который он указывает?
Я знаю что он не валидный! Но почему при F5, тоесть когда я с прожкой запускаю дебаггер то все чудесно, цветочки, мир ии все друг-друга любят, все валидны и счастливы! А вот когда CTRL + F5 то все счастливы до деструктора а потом приходят невалидные указатели и ламают всем(тоесть мне) кайф!

Пойду куплю веревку, уже 4 день еб... мучаюсь и ничего не выходит smile

Автор: Earnest 16.1.2007, 18:09
А, оба раза дебаг? Не надо вешаться, все там были. Главное, всегда помнить: мистики нет, есть ошибка.
Терпи и вырабатывай интуицию... потом позвоночником начнешь ошибки искать...

Распечатывай, конечно, содержимое... хотя и по значению указателя иногда видно, что он левый... 
Я полагаю, что указатели портятся где-то еще, т.к. приведенный тобою код удаления вроде нормальный.
В зависимости от величины программы, я бы попробовала (в следующем порядке): 
1) просмотреть код, который теоретически может портить указатели и попытаться логически найти ошибку
2) комментировать другие куски кода (оставляя заглушки вместо нужных функций), пока не обнаружится тот, кто приводит к порче. Начать с комментирования всего, кроме создания и удаления.
3) Используя ф-ю heapwalk написать проверку валидности указателей в массивах. Затем вставлять ее в разных точках и искать, где портится.


Автор: _hunter 16.1.2007, 18:19
ну и я свои 5 копеек вставлю: есть такая замечательная програмка BoundsChecker. она, кроме всего прочего, умеет и неправильные операции над указателями отслеживать...

Автор: Nuzur 17.1.2007, 12:45
Earnest, суть в том что при обращении к невалидному указателю все завалиться, тоесть я не могу посмотреть "Что же там".
Код сейчас составляет загрузку их xml и при завершении программы выгрузку в xml изменений,  Которых небыло. Тоесть испортиться если он создался его может только винда и любимая студия.
Тоесть я создаю в памяти сию структуру(и я ее создаю и пишу в нее правильные значения так говорит великий дебаггер), а потом жестоко уничтожаю при закрытии программы(и по словам тоже авторитета дебаггера это у меня все правильно тоже).
Но вот косяк я не могу конечному пользователю об'яснить что ему надо будет запускать прогу теперь из под дебагерра smile точнее могу но тим-лидер тогда научит меня тому чему я учиться не хочу, ибо я свято убежден что мне не понравиТЬся.

По существу. 1 - сейчас и знамаюсь. 2 не столько еще наворотил 3. Можна ли поподробнее?


_hunter, Спасибо не знал етого. Щя буду ставить.

Автор: Nuzur 17.1.2007, 18:35
Нашел где косяк. Не могу понять почему!
Код

for(j = 0; j < mapIdColorRTU.GetValueAt(i)->GetSize(); j++)

 
вызывается на 1-н раз больше чем надо! Там записываю одно значение, функцией Add а в деструкторе вызывается два!
Не понимаю почему smile

Автор: Earnest 18.1.2007, 10:49
Цитата(Nuzur @  17.1.2007,  13:45 Найти цитируемый пост)
суть в том что при обращении к невалидному указателю все завалиться, тоесть я не могу посмотреть "Что же там".

Вовсе не всегда, только если указатель показывает в защищенную область, но тогда это по указателю видно.

Цитата(Nuzur @  17.1.2007,  13:45 Найти цитируемый пост)
Тоесть испортиться если он создался его может только винда и любимая студия.

С чего ты взял? Испортиться может что угодно - достаточно, чтобы какой-то левый код записал что-то не в свою память.

Цитата(Nuzur @  17.1.2007,  19:35 Найти цитируемый пост)
вызывается на 1-н раз больше чем надо

Кто именно? В mapIdColorRTU лишние значения? Или в его значениях?
Сам цикл подозрений не вызывает - он работает столько раз, сколько говорит GetSize - если, конечно ты внутри цикла не химичишь с размером массива. Стало быть, ищи где лишнее значение туда попадает. Может, когда ты Add вызываешь, там что-то уже есть? Выводи размер при добавлении и при удалении.

Автор: Nuzur 22.1.2007, 11:25
Нашел багу smile хорошо что заболел и немного голова разгрузилась, а то месяцами бы в код смотрел smile

Earnest и _hunter жду вас господа smile

короче, вместо
Код

    int i,j,k;
    for(i = 0; i < mapIdColorRTU.GetSize(); i++)
    {
        for(j = 0; j < mapIdColorRTU.GetValueAt(i)->GetSize(); j++)
            for(k = 0; k < mapIdColorRTU.GetValueAt(i)[j].GetSize(); k++)
            {
                delete (ColorPtr)mapIdColorRTU.GetValueAt(i)[j][k]; // здеся вот валиться :(
            }
        mapIdColorRTU.GetValueAt(i)->RemoveAll();
        delete mapIdColorRTU.GetValueAt(i);
    }


Нужно было
Код

    int i,j;
    for(i = 0; i < mapIdColorRTU.GetSize(); i++)
    {
        for(j = 0; j < mapIdColorRTU.GetValueAt(i)->GetSize(); j++)
        {
            delete (*mapIdColorRTU.GetValueAt(i))[j];

        }
    }


И ничего не валится. Хотя муть-то полная, а вот кто пояснит мне почему срабатывало когда было неправильно!? Ведь не долно ж юыло так работать! Я уже совсем запутался smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)