调用删除函数后双向链表不接受输入

Doubly linked list not taking input after calling a delete function

问候堆栈溢出。我的程序应该接受用户输入的字符行并将它们附加到列表中。如果在输入中读取主题标签,该程序还应该删除附加的最新字符。

我的程序 大部分都可以工作 ,但是当我试图通过添加太多主题标签来破坏它时,我 运行 出错了。执行此操作后,列表将停止接受追加,如果使用的主题标签过多,则不会显示任何内容。

我希望我只包含了我认为有用的代码,如果 main 函数不是必需的,请见谅。

#include <iostream>
using namespace std;


class doubleList
{
    public:
        doubleList() { first = NULL; } // constructor

        void append(char); // adds entry to the end of the list
        void remove_last(); // removes the last item from a list

        friend ostream& operator<<(ostream& out, const doubleList& l); // outputs in forward order

    private:
        struct Node
        {
            char data;
            Node *next;
            Node *prev;
        };
        Node *first;
        Node *last;  
};

void doubleList::append(char entry)
{
    Node* temp = new Node();
    temp -> data = entry;
    temp -> next = NULL;

    if (first == NULL)
    {
        first = temp;
        last = temp;
    }
    else
    {
        last -> next = temp;
        temp -> prev = last;
        last = temp;
    }
}

void doubleList::remove_last()
{
    if (first -> next == NULL)
    {
        delete first;
    }
    else if (first != NULL)
    {
        last = last -> prev;
        delete last -> next;
        last -> next = NULL;
    }
}

ostream& operator<<(ostream& out, const doubleList& l)
{
    doubleList::Node* q;
    q = l.first;

    while (q != NULL)
    {
        out << q -> data;
        q = q -> next;
    }
    return out;
}

int main()
{
    doubleList list;
    char ch[100];

    cout << "Enter a line of characters; # will delete the most recent character." << endl;
        for (int i = 0; i < 100; i++)
        {
            cin.get(ch[i]);
            list.append(ch[i]);

            if (ch[i] == '#')
            {
                list.remove_last();
                list.remove_last(); // called twice becaue it removes the hashtag from the list
            }                       // and i was too lazy to make it so it doesnt do that so this
                                    // is simply an easier fix
            if (ch[i] == '\n')      // exits the loop when enter is clicked
                break;
        }

    cout << list;

    return 0;
}

我的程序的成功 运行 看起来像:

Enter a line of characters; # will delete the most recent character.

abcd##fg

abfg

我的程序添加了太多主题标签时:

Enter a line of characters; # will delete the most recent character.

ab#####efgh

用户输入后不显示任何内容。提前致谢。

remove_last() 中解除分配时,您依​​赖于首先为 NULL,但不要在 free 之后设置它。由于您的代码不完整,我无法分辨 last 是什么,以及为什么您的逻辑不依赖于 remove_last() 而不是 first.

类似的东西(未经测试);

void doubleList::remove_last() {
    if(!last) return;

    if(last == first) {
       free last;
       first = nullptr;
       last = nullptr;
       return;
    }
  
    last = last->prev;
    free last->next;
    last->next = nullptr;
}

您还应该在构造函数中将指针 last 设置为 nullptr

doubleList() { first = nullptr; last = nullptr; }

函数append不正确,因为它没有设置附加到列表的第一个节点的数据成员prev。应该写成

void doubleList::append(char entry)
{
    Node* temp = new Node();
    temp -> data = entry;
    temp -> next = nullptr;
    temp -> prev = last; 

    if (first == NULL)
    {
        first = temp;
    }
    else
    {
        last -> next = temp;
    }

    last = temp;
}

函数 removeList 可以调用未定义的行为,因为在函数的最开始它不检查指针 first 是否等于 nullptr。而在删除指针first指向的节点后,它并没有将指针firstlast设置为nullptr。该函数可以通过以下方式定义。

void doubleList::remove_last()
{
    if ( last )
    {
        Node *tmp = last;

        last = last->prev;

        if ( last != nullptr )
        {
            last->next = nullptr;
        }
        else
        {
            first = nullptr;
        }

        delete temp;
    }
}