2010-04-17 6 views
3

У меня проблема с удалением и деструктором (я уверен, что делаю глупую ошибку здесь, но пока не могу понять это).C++ delete не работает?

Когда я перехожу в деструктор и пытаюсь вызвать delete на указателе, появляется сообщение «Невозможно получить доступ к памяти по адресу с некоторым адресом».

Соответствующий код:

/* 
* Removes the front item of the linked list and returns the value stored 
* in that node. 
* 
* TODO - Throws an exception if the list is empty 
*/ 
std::string LinkedList::RemoveFront() 
{ 
    LinkedListNode *n = pHead->GetNext(); // the node we are removing 
    std::string rtnData = n->GetData(); // the data to return 

    // un-hook the node from the linked list 
    pHead->SetNext(n->GetNext()); 
    n->GetNext()->SetPrev(pHead); 

    // delete the node 
    delete n; 
    n=0; 

    size--; 
    return rtnData; 
} 

и

/* 
* Destructor for a linked node. 
* 
* Deletes all the dynamically allocated memory, and sets those pointers to 0. 
*/ 
LinkedListNode::~LinkedListNode() 
{ 
    delete pNext; // This is where the error pops up 
    delete pPrev; 
    pNext=0; 
    pPrev=0; 
} 

ответ

5

кажется, что вы удаляете следующие и предыдущие узлы списка из деструктора. Что, если pNext и pPrev являются LinkedListNode* означает, что вы рекурсивно удалить весь список :-(

Попробуйте это:

std::string LinkedList::RemoveFront() 
{ 
    LinkedListNode *n = pHead->GetNext(); // the node we are removing 
    std::string rtnData = n->GetData(); // the data to return 

    // un-hook the node from the linked list 
    pHead->SetNext(n->GetNext()); 
    n->GetNext()->SetPrev(pHead); 

    n->SetNext(0); 
    n->SetPrev(0); 
    // delete the node 
    delete n; 
    n=0; 

    size--; 
    return rtnData; 
} 

LinkedListNode::~LinkedListNode() 
{ 
} 

(На самом деле вам не нужно даже сбросить предыдущую и следующую указатели до 0, так как вы все равно собираетесь удалить узел. Я оставил эти операторы, потому что они по крайней мере помещают узел в согласованное состояние, что является хорошей идеей в целом. Это может иметь значение, если позже вы измените управление памятью стратегии и решить сохранить неиспользуемые узлы для последующего повторного использования.)

+0

Следующий и предыдущие узлы, хранящиеся в текущем узле (каждый узел содержит некоторые строковые данные, а также указатель на следующий и предыдущие узлы в списке). Это желаемое поведение, так как мы не подключили этот узел из связанного списка и теперь хотим вернуть всю динамически выделенную память EDIT - подождите, я думаю, посмотрите, что вы говорите. – vimalloc

+0

@kyeana: вы только хотите вернуть память, связанную с единственным узлом, который вы удаляете –

+3

Это хуже, чем это - это фактически будет удалять вперед до конца списка (рекурсия при первом удалении), а затем попытаться удалить второй-последний узел снова изнутри деструктора последнего узла, что, вероятно, является причиной сбоя. Если X, Y и Z являются последними тремя узлами, ~ X удаляет Y, ~ Y удаляет Z, а ~ Z снова удаляет Y. –

1

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

Кроме того, ваш LinkedListNode деструктор проблематично даже в том случае, если вы хотите, чтобы весь список, подлежащих уничтожению: наличие как delete pNext и delete pPrev приведет к несколько вызовов одного и того же деструктора (и я думаю, что в конце концов переполнение стека).

+0

oh god ... node 2 удаляет узлы 1 и 3, которые оба пытаются удалить узел 2, который дважды удаляет узлы 1 и 3, а затем узел 2 снова удаляется четыре раза, ... –

0

На самом деле вам не следует возиться с соседями в узле. Это для класса списка - соедините их правильно. В деструкторе вы можете установить их в null, но если вы не выделили динамически что-то еще - вам не нужно звонить delete