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


Автор: fish9370 21.4.2007, 09:41
Код

void dyList::DeleteSubstance(Element *pThis)
{
    if(pThis->szItem)
    {
        delete pThis->szItem;
        pThis->szItem=NULL;
    }
}


у кого какие соображения, как может получиться, что строка "delete pThis->szItem;" может ссылаться на чужую область памяти? это при том, что указатель pThis не был взят с потолка и имеет верные значения..

Автор: Anikmar 21.4.2007, 11:09
Предположение:
1. Неправильно инициируется szItem
2. Адрес не того объекта передается.

Автор: fish9370 21.4.2007, 13:33
создание и инициализация производится вот так:

Код

nPos=nSPos=0;
while((nPos=FindNext("\r\n\r",szRecvBuff,nPos))>=0)      //put find word here
{
    pThis=EventChain.New();
    pThis->szItem=new char[nPos-nSPos];
    strCopy(szRecvBuff,pThis->szItem,nSPos,nPos);
    nSPos=nPos;
}


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

это выглядит вот так:

Код

EventChain.Del(EventChain.First());


метод удаления выглядит так:

Код

Element* dyList::Del(Element *pElmnt)      //debuged [15.04.07]
{
    if(!pElmnt) return NULL;

    Element *pThis=pElmnt;
    if(pElmnt->pNext)
        pElmnt->pNext->pPrev=pElmnt->pPrev;
    if(pElmnt->pPrev)
        pElmnt->pPrev->pNext=pElmnt->pNext;
    if(pElmnt->pNext)                      //false, if pElmnt==pLast
        pElmnt=pFirst=pElmnt->pNext;
    else if(pElmnt->pPrev)
            pElmnt=pLast=pElmnt->pPrev;
         else pElmnt=pFirst=pLast=NULL;    //it was the Last Element
    DeleteSubstance(pThis);
    delete pThis;
    pThis=NULL;
    nCount--;
    return pElmnt;
//return next element address or previous, if it was last or NULL, if it was the Last
}


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

Автор: dizzy1984 21.4.2007, 15:33
Возможно дело в том, что память выделенная с помощью
Код

new []

должна удаляться с помощью
Код

delete []


попробуйте поменять
Код

 delete pThis->szItem;


на

Код
 
delete [] pThis->szItem;


Автор: fish9370 21.4.2007, 16:35
2 Dizzi1984 ты не поверишь, незадолго до твоего сообщения, я точно так же подумал.. и поставил эти квадратные скобки, ровно в том месте, в котором ты предложил.. к несчастью, это не помогло.. может еще какие-то идеи?

Автор: Anikmar 21.4.2007, 17:47
Если под трассировкой все работало, то конечно врядли в этом дело, но я совершенно не понял вот этого участка:
Код

   if(pElmnt->pNext)                      //false, if pElmnt==pLast
        pElmnt=pFirst=pElmnt->pNext;
    else if(pElmnt->pPrev)
            pElmnt=pLast=pElmnt->pPrev;
         else pElmnt=pFirst=pLast=NULL;    //it was the Last Element

Автор: fish9370 21.4.2007, 20:00
Anikmar я так был восхищен своим кодом и мания упрощать все и вся, привели меня к подобным ошибкам.. эту ошибку я исправил (на которую ты указал).. но ошибка, главная ошибка, все еще беспокоит меня.. но ты показал мне, что мой код все еще дыряв как операционнная система виндоуз (не в обиду Биллу сказанно).. и за это тебе спасибо..

сейчас еще раз тщательно пробегусь отладчиком.. если есть еще какие мысли, был бы рад услышать..

Автор: Anikmar 21.4.2007, 20:36
У меня возникло впечатление, что все дело в пограничных случаях удаления элемента из цепочки... Именно по этому ошибка проявляется не сразу, а по достижения некого критерия - список пуст или в нем осталось 1 или 2 элемента и т.п.

Вообще-то я пока не писал серьезные многопоточные вещи, а так пару раз баловался, но даже с небольшими экспериментами я препочитал писать все в Лог - ошибки ловятся на ура.

Автор: fish9370 22.4.2007, 00:45
Цитата(Anikmar @ 21.4.2007,  20:36)
У меня возникло впечатление, что все дело в пограничных случаях удаления элемента из цепочки... Именно по этому ошибка проявляется не сразу, а по достижения некого критерия - список пуст или в нем осталось 1 или 2 элемента и т.п.

Вообще-то я пока не писал серьезные многопоточные вещи, а так пару раз баловался, но даже с небольшими экспериментами я препочитал писать все в Лог - ошибки ловятся на ура.

ты же понимаешь, что именно так я и делаю.. все без толку.. могу логи привести.. я уже думаю, что это связанно как-то с потоками.. он сбоит абсолютно хаотично.. завтра буду думать.. сегодня начал с другого конца, делал интерфейс.. к среде нужно прогу предоставить.. хотябы бета-версию..

Автор: Anikmar 22.4.2007, 00:54
Цитата(fish9370 @  22.4.2007,  00:45 Найти цитируемый пост)
ты же понимаешь, что именно так я и делаю.. все без толку.. могу логи привести.. я уже думаю, что это связанно как-то с потоками.. он сбоит абсолютно хаотично.. завтра буду думать.. сегодня начал с другого конца, делал интерфейс.. к среде нужно прогу предоставить.. хотябы бета-версию.. 


Ну тогда если только что-то с синхронизацией. Когда функция удаления узла влетает на реентерабельность, а судя по коду она там не поддерживается... Больше ничего в голову не приходит.

Автор: fish9370 22.4.2007, 17:08
докопался наконец.. оказывается, я просто не расчитал размер буфера под строку.. выделял впритык.. накинул еще 10 байт появилась стабильность и счастье.. всем еще раз спасибо..

вот как надо было:
Код

nPos=nSPos=0;
while((nPos=FindNext("\r\n\r",szRecvBuff,nPos))>=0)      //put find word here
{
    pThis=EventChain.New();
    pThis->szItem=new char[nPos-nSPos+10];
    strCopy(szRecvBuff,pThis->szItem,nSPos,nPos);
    nSPos=nPos;
}

Автор: fish9370 22.4.2007, 19:56
спасибо..

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