【问题标题】:C++ Linked List BreakPoint Error with deletionC++ 链表断点错误与删除
【发布时间】:2020-11-07 04:46:59
【问题描述】:

嘿,我正在尝试创建一个链表,计算从头到尾添加元素所需的时间。然后从头到尾删除then。我有添加和删除的代码,但是当我从列表中删除最后一个元素时,我遇到了一个涉及内存分配的断点错误。我猜我需要在列表为空时添加故障保护,但我不知道该怎么做。

非常感谢一些建议,因为我对此很陌生。

谢谢!

我的列表类代码:

class list
{
public:
    struct node {
        int data;
        struct node* next;
    } *head, *tail;

    list() :head(NULL), tail(NULL) {}   // constructor  

    ~list() {
        node* current, * temp;
        current = head;
        temp = head;
        while (current != NULL) {
            current = current->next;
            delete temp;
            temp = current;
        }
    }

    // adding to the end of list  
    void addToEnd(int n) {
        node* newNode = new node;
        newNode->data = n;
        newNode->next = NULL;

        if (head == NULL) {
            head = newNode;
            return;
        }
        node* cur = head;
        while (cur) {
            if (cur->next == NULL) {
                cur->next = newNode;
                return;
            }
            cur = cur->next;
        }
    }
    
    //Add to beginning
    void addToBeginning(int n) {
        node* newNode = new node;
        newNode->data = n;
        newNode->next = NULL;

        if (head == NULL) {
            head = newNode;
            return;
        }
        else {
            newNode->next = head;
            head = newNode;
        }
        
    }

    void deleteFromBeginning() {
        if (head != NULL) {
            node* temp = head->next;
            delete head;
            head = temp;
        }
        if (head == NULL) {
            cout << "Nothing to delete" << endl;
            return;
        }
    }

    void deleteFromEnd() {
        node* removeLastNode = head;
            if (head == NULL)
                return;

            if (head->next == NULL) {
                delete head;
                return;
            }

            // Find the second last node 
            node* second_last = head;
            while (second_last->next->next != NULL)
                second_last = second_last->next;

            // Delete last node 
            delete (second_last->next);

            // Change next of second last 
            second_last->next = NULL;

        }

    //Display List
    void displayList() {
        if (head != NULL) {
// This was also triggering an access violation error when I tried to run this after the delete loop
            for (node* temp = head; temp != NULL; temp = temp->next) { 
                cout << temp->data << " ";
            }
            cout << endl;
        }
    }

};

我想将它保存在一个单独的类中,因为它将成为更大程序的一部分,并且我想最小化主源文件中的代码。

这里是主要的代码:

int main() {
    int data;
    list myList;

    for (int i = 0; i < 10; i++){
        myList.addToBeginning(i);
    }
    myList.displayList();

    for (int i = 0; i < 5; i++) {
        myList.deleteFromBeginning();
    }
    myList.displayList();

    for (int i = 0; i < 10; i++) {
        myList.addToEnd(i);
    }
    myList.displayList();

    for (int i = 0; i < 15; i++) {
        myList.deleteFromEnd(); // Error comes here
    }
}

【问题讨论】:

  • “断点错误” -- 没有这样的东西。您可能的意思是您在调试器中运行它,并且当检测到严重错误(可能的崩溃)时,调试器中断了执行。 大家好!由于您使用的是调试器,因此您可以检查变量的值以更好地了解问题所在。
  • 请使用较小的minimal reproducible example。您怀疑删除最后一个元素是有问题的。因此,将您的 main 函数缩减为将 single 元素添加到列表中,然后删除该元素。如果崩溃仍然存在,请删除所有不需要的代码来支持这个更小的main()例外: 您可能需要先查看deleteFromBeginning(),然后再将其从示例中删除。您在该函数中做了一些 deleteFromEnd() 中缺少的事情。
  • 已经把它剪掉了,可能我不完全理解指针在这里是如何工作的。这是我仍然收到的消息:抛出异常:读取访问冲突。 second_last->next 是 nullptr。
  • 没关系,我已经解决了。必须检查列表是否有多个项目,然后启动 while 循环。

标签: c++ linked-list singly-linked-list


【解决方案1】:

必须检查列表是否有多个项目,然后启动 while 循环。当我只剩下 1 个节点时,它导致了一个问题。

void deleteFromEnd() {
            node* temp;
            if (head == NULL)
            {
                cout << " There is no item to delete!" << endl;
                return;
            }
            node* start = head;
            if (start->next != NULL)
            {
                while ((start->next)->next != NULL)
                {
                    start = start->next;
                }
                temp = start->next;
                start->next = NULL;
            }
            else
            {
                temp = start;
                head = NULL;
            }
            delete temp;
        }

【讨论】:

  • 您的修复看起来不错,但您的分析已关闭。如果列表只有一项,则问题中此函数的版本也会通过 if (head-&gt;next == NULL) 行跳过循环。所以这种改变不是解决办法。这个答案的关键改进是在删除列表中的最后一项时更新head(通过分配head = NULL)。
猜你喜欢
  • 2019-05-10
  • 2021-07-25
  • 1970-01-01
  • 1970-01-01
  • 2016-06-05
  • 1970-01-01
  • 2020-04-19
  • 2017-10-21
  • 2013-08-30
相关资源
最近更新 更多