3

削除とデストラクタに問題があります(ここで愚かな間違いを犯していると確信していますが、現時点ではそれを理解できていません)。

デストラクタにステップスルーし、ポインタで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;
}
4

3 に答える 3

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にリセットする必要はありません。少なくともノードを一貫性のある状態にするため、これらのステートメントを残しました。これは、一般。後でメモリ管理戦略を変更し、後で再利用するために未使用のノードを保存することを決定した場合、違いが生じる可能性があります。)

于 2010-04-17T20:56:19.680 に答える
1

隣接するノードを削除しているようです。LinkedListNodeそのため、1つのノードを削除すると、リスト全体が破棄されます。ノードを削除するときは、設定せずpNextpPrevNULLに設定しないでください。

また、LinkedListNodeリスト全体を破棄したい場合でも、デストラクタには問題があります。両方delete pNextを持ってdelete pPrevいると、同じデストラクタが複数回呼び出されます(最終的にはスタックオーバーフローになると思います)。

于 2010-04-17T20:58:27.363 に答える
0

実際、ノード内の隣人をいじってはいけません。それはリストクラスが行うことです-それらを適切に接続します。デストラクタでは、それらをnullに設定できますが、何か他のものを動的に割り当てていない限り、呼び出す必要はありませんdelete

于 2010-04-17T20:59:59.430 に答える