首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >指针丢失对前一个节点C++的引用

指针丢失对前一个节点C++的引用
EN

Stack Overflow用户
提问于 2017-09-12 23:55:55
回答 2查看 610关注 0票数 0

我在写一个程序来学习双链接列表。我似乎无法调试的问题是,调试器给我一个写访问冲突,并且声明prevNode>next或nextNode->prev指向null。当您尝试从nth位置删除节点时,就会发生这种情况。我已经删除了这篇文章的部分代码,以使其更短、更容易阅读,因此有些变量看起来可能没有用到。

调试器通常停止的部分是删除节点之前的最后一行:

代码语言:javascript
运行
复制
nextNode = nodePtr->next;
prevNode = nodePtr->prev;
nextNode->prev = prevNode;
prevNode->next = nextNode;
delete(nodePtr);

对于删除列表开头和结尾的节点,我知道需要不同的代码(if语句),以确保prevNode>next和nextNode->prev没有设置为不存在的节点。问题是,即使我试图删除不在列表开头或结尾的节点,它也会给我带来这些错误。

任何帮助或推动一个正确的方向将是非常感谢的!

代码语言:javascript
运行
复制
#include <iostream>
using namespace std;

int main() {

    struct ListNode {
        int value;
        ListNode *next;
        ListNode *prev;
    };

    ListNode *head = nullptr;
    ListNode *newNode = nullptr;
    ListNode *nodePtr = nullptr;
    ListNode *prevPtr = nullptr;
    ListNode *nextNode = nullptr;
    ListNode *prevNode = nullptr;

    char ch = 'q';
    int val;
    int pos;

    do
    {
        cout << "h-delete from position" << endl;
        cout << "i-insert" << endl;
        cout << "p-print" << endl;
        cout << "q-quit" << endl;

        cin >> ch;

        switch (ch) {

        case 'i':

            cout << "inserting ... \n";
            cout << "Enter an integer: ";
            cin >> val;

            newNode = new ListNode;
            newNode->value = val;
            newNode->next = nullptr;

            if (head == nullptr) {
                head = newNode;
            }
            else {
                nodePtr = head;
                prevPtr = nullptr;

                while (nodePtr != nullptr && nodePtr->value < newNode->value) {
                    prevPtr = nodePtr;
                    nodePtr = nodePtr->next;
                }
                if (prevPtr == nullptr) {
                    head = newNode;
                    newNode->next = nodePtr;
                }
                else {
                    prevPtr->next = newNode;
                    newNode->next = nodePtr;
                }

            }
            break;

        case 'p':

            cout << "printing ... \n";
            nodePtr = head;
            while (nodePtr != nullptr) {
                cout << "elem: " << nodePtr->value << endl;
                nodePtr = nodePtr->next;
            }
            break;

        case 'h':
            //FIX
            int findVal;
            cin >> findVal;


            nodePtr = head;
            while (nodePtr->value != findVal) {
                nodePtr = nodePtr->next;
            }
            nextNode = nodePtr->next;
            prevNode = nodePtr->prev;
            nextNode->prev = prevNode;
            prevNode->next = nextNode;
            delete(nodePtr);

            break;

        case 'q':

            cout << "quitting ... \n";
            nodePtr = head;
            while (nodePtr != nullptr) {
                nextNode = nodePtr->next;
                cout << "deleting ... " << nodePtr->value << endl;
                delete nodePtr;
                nodePtr = nextNode;
            }

            break;

        default:
            system("CLS");
            cout << "Invalid character -- Please try again!" << endl;
            break;
        }

    } while (ch != 'q');


    system("pause");
    return 0;
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-09-13 00:06:44

这一行将失败:

代码语言:javascript
运行
复制
prevNode = nodePtr->prev;
.....
prevNode->next = nextNode;

因为在插入节点时不为prev提供值。所以prevNode永远是nullptr

在调试器中逐行遍历将帮助您找到这些类型的bug。

票数 1
EN

Stack Overflow用户

发布于 2017-09-13 00:08:03

h情况下,如果输入一个不存在的值,您将尝试在空地址使用该对象。

另外,如果删除第一个节点( head),它将不会被更新,因此在此之后的任何其他操作都会失败,因为您使用的是被破坏的对象,这是未定义的行为。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46186867

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档