【问题标题】:Linked-list destructor crashes C++ program链表析构函数使 C++ 程序崩溃
【发布时间】:2014-12-15 23:45:07
【问题描述】:

我一直在为链表项目开发析构函数,其中偶数插入前面,奇数插入后面。删除工作在后进先出,具体取决于它是奇数还是偶数。我一切正常,但是当我运行我的析构函数时我不断收到错误。我已经完成了调试,它删除了所有节点,但之后崩溃了,我不知道为什么。这是我的代码:

//Headerfile
class Staque
{
private:
struct staqueNode
{
    int value;
    struct staqueNode *next;
    struct staqueNode *prev;
};

staqueNode *root;


public:
Staque();
~Staque();

void addNode(int addIn);
void deleteNode(int oddIn, int evenIn);
void display();
};

//header.cpp file
#include"Staque.h"
#include<iostream>

using namespace std;

Staque::Staque()
{
root = NULL;    
}

void Staque::addNode(int addIn)
{
staqueNode *newNode;
staqueNode *nodePtr;
staqueNode *temp = NULL;

newNode = new staqueNode;
newNode->value = addIn;
newNode->next = NULL;
newNode->prev = NULL;
if (!root)
{
    root = newNode;
}
else
{
    if (newNode->value % 2 == 0)
    {
        nodePtr = root;
        while (nodePtr->next)
        {
            nodePtr = nodePtr->next;
        } 
        nodePtr->next = newNode;
        newNode->prev = nodePtr;
    }
    else if (newNode->value % 2 != 0)
    {
        nodePtr = root;
        while (nodePtr->prev)
        {
            nodePtr = nodePtr->prev;
        }
        nodePtr->prev = newNode;
        newNode->next = nodePtr;
    }
}
} 
void Staque::deleteNode(int oddIn, int evenIn)
{
staqueNode *nodePtr;
staqueNode *temp = NULL;
if (!root)
    return;
while (evenIn > 0)
{
    nodePtr = root;
    while (nodePtr != NULL && nodePtr->next != NULL)
    {
        temp = nodePtr;
        nodePtr = nodePtr->next;
    }
    if (nodePtr == root && root->value % 2 == 0)
    {
        root = root->prev;
        temp->next = NULL;
        delete nodePtr;
        evenIn = 0;
    }
    else
    {
        temp->next = NULL;
        delete nodePtr;
        evenIn -= 1;
    }
}

while (oddIn > 0)
{
    nodePtr = root;
    while (nodePtr != NULL && nodePtr->prev != NULL)
    {
        temp = nodePtr;
        nodePtr = nodePtr->prev;
    }
    if (nodePtr == root && root->value % 2 != 0)
    {
        root = root->next;
        temp->prev = NULL;
        delete nodePtr;
        oddIn = 0;
    }
    else
    {
        temp->prev = NULL; 
        delete nodePtr;
        oddIn -= 1;
    }
}

}

void Staque::display()
{
staqueNode *nodePtr;

nodePtr = root;
while (nodePtr->next)
{   
    nodePtr = nodePtr->next;
}
cout << "\nThe staque: ";
while (nodePtr->prev)
{
    cout << nodePtr->value << " ";
    nodePtr = nodePtr->prev;
}
cout << nodePtr->value << endl;

}

Staque::~Staque()
{
staqueNode *nodePtr;
staqueNode *temp;
nodePtr = root;

while (nodePtr->next)
{
    temp = nodePtr;
    nodePtr = nodePtr->next;
}
//nodePtr = root;
while (nodePtr->prev)
{
    temp = nodePtr;
    nodePtr = nodePtr->prev;
    delete temp;
}
//delete root;

}


//source/main.cpp
#include"Staque.h"
#include<iostream>


using namespace std;

int main()
{
Staque myList;
int choice;
int input;
int numOdd;
int numEven;

do
{
    cout << "Would you like to: \nAdd a node: 1\nDelete a node: 2\nDisplay the list: 3\nQuit: 0\n";
    cin >> choice;
    while (choice < 0 || choice > 3)
    {
        cout << "Invalid Input: Would you like to: \nAdd a node: 1\nDelete a node: 2\nDisplay the list: 3\nQuit: 0\n";
        cin >> choice;
    }
    switch (choice)
    { 
    case 1:
        cout << "Enter the value you would like to add to the list: ";
        cin >> input;
        while (isalpha(input))
        {
            cout << "Invalid input: Enter the value you would like to add to the list: ";
            cin >> input;
        }
        myList.addNode(input);
        myList.display();
        break;

    case 2:
        cout << "Enter the number of even numbers you would like to delete: ";
        cin >> numEven;
        while (isalpha(input) || numEven < 0)
        {
            cout << "Invalid input: Enter the number of even numbers you would like to delete: ";
            cin >> numEven;
        }

        cout << "Enter the number of odd numbers you would like to delete: ";
        cin >> numOdd;
        while (isalpha(input) || numEven < 0)
        {
            cout << "Invalid input: Enter the number of odd numbers you would like to delete: ";
            cin >> numOdd;
        }
        myList.deleteNode(numOdd, numEven);
        myList.display();
        break;

    case 3:
        myList.display();
        break;

    default:
        break;

    }
} while (choice != 0);

myList.~Staque();

return 0;

}

【问题讨论】:

  • I have everything working but I keep getting an error when I run my destructor 这可能意味着一大堆工作。另外,请修正您的格式。
  • 我怀疑你没有遵守Rule of Three
  • myList.~Staque(); ??!!你为什么做这个?删除它。
  • @PaulMcKenzie:很好的收获。这可能是原因!
  • @JBoyden 实际上你的代码糟糕!调试,单步执行。调试,有断点。调试,追溯引发异常的堆栈帧。

标签: c++ linked-list destructor delete-operator


【解决方案1】:

一个明显的错误是你明确地调用了你的析构函数。

myList.~Staque();

您不应该这样做——当对象超出范围时,它会自然而然地“死亡”。通过显式调用析构函数,对象将调用析构函数,然后当对象超出范围时将再次调用析构函数。这是第二次调用将导致所有破坏。

你应该明确调用析构函数的时间是你使用placement-new,而你在这里没有这样做。因此,只需删除上面的那一行,看看错误是否消失。如果没有,那么您还有更多问题,但至少您可以从代码中删除这个明显的问题。

【讨论】:

  • 谢谢,这解决了我遇到的错误。我想我必须明确调用它,否则它会留下内存在使用中。
【解决方案2】:

具体看你的析构函数...

当 nodePtr 为空时会发生什么?例如,您没有创建节点。

或者你到达最后一个节点,它总是将下一个 ptr 设置为 NULL,然后你在一个空指针上取消引用 nodePtr->next - 是的,你猜它崩溃了。

在你的 while (nodePtr->next) 中,临时分配在做什么?好像没什么用。

while (nodePtr->prev) ???

不检查 nodePtr 是否为空?

这就是开始。

你确定其余的都可以吗?

【讨论】:

    猜你喜欢
    • 2017-06-28
    • 1970-01-01
    • 1970-01-01
    • 2021-07-16
    • 2011-06-12
    • 1970-01-01
    • 2012-09-29
    • 2017-11-21
    • 1970-01-01
    相关资源
    最近更新 更多