Это код С++ для связанного списка. после установки значения ch=1 он добавит узел с некоторым значением, но после установки одного значения программа неожиданно закрывается

#include <iostream>
using namespace std;

class Node{
    public:
        int data;
        Node *next;
};
int main()
{
    Node *head=NULL;
    Node *temp;
    Node *nodeToAdd;
    int ch,val,flag=1;
    while(flag){
        cout<<"\n1.Add   2.Traverse   3.EXIT\n";
        cin>>ch;
        switch(ch){
            case 1:
                nodeToAdd=new Node();
                cout<<"Enter value - ";
                cin>>val;
                cout<<endl;
                nodeToAdd->data=val;
                temp=head;
                while(temp->next!=NULL){
                    temp=temp->next;
                }
                temp->next=nodeToAdd;
                break;
            case 2:
                temp=head;
                while(temp!=NULL){
                    cout<<temp->data;
                    temp=temp->next;
                }
                break;
            case 3:
                flag=0;
                break;
        }
    }
    return 0;
}

Пожалуйста, скажите мне мою ошибку, почему программа неожиданно завершает работу после установки значения ch = 1. После установки значения ch 1 он принимает один вход в качестве значения и после этого неожиданно завершается.


person Naman Verma    schedule 04.08.2021    source источник
comment
Пожалуйста, напишите тест, который не зависит от интерактивного ввода. Интерактивные модульные тесты на самом деле не очень полезны, и вы можете также исключить цикл ввода как возможную причину.   -  person Useless    schedule 04.08.2021
comment
Рассмотрите возможность перемещения этих случаев в их собственные функции. Возложите слишком большую ответственность на одну функцию, и вам будет гораздо труднее доказать, что поведение функции правильное.   -  person user4581301    schedule 04.08.2021


Ответы (2)


Прежде чем делать:

            temp=head;
            while(temp->next!=NULL){

вам нужно проверить, является ли head NULL. Нравиться

        if (head == NULL)
        {
            // ... Do stuff to insert first element
        }
        else
        {
            // Add to end of list
            temp=head;
            while(temp->next!=NULL){
            ...
person 4386427    schedule 04.08.2021

Этот фрагмент кода

temp=head;
while(temp->next!=NULL){
    temp=temp->next;
}
temp->next=nodeToAdd;

уже вызывает неопределенное поведение, потому что изначально указатель head может быть нулевым указателем, а разыменование нулевого указателя в выражении temp->next!=NULL дает неопределенное поведение.

Также вы забыли установить для члена данных next добавленного узла значение nullptr.

Измените фрагмент кода под меткой case 1: следующим образом

case 1:
    cout << "Enter value - ";
    cin >> val;
    cout << endl;

    nodeToAdd = new Node { val, nullptr };

    if ( head == nullptr )
    {
        head = nodeToAdd;
    }
    else
    { 
        temp = head;
        while ( temp->next ) temp = temp->next;
        temp->next = nodeToAdd;
    }
    break;
person Vlad from Moscow    schedule 04.08.2021
comment
В интересах OP: это одна из причин, по которой иногда бывает полезно добавить дозорный узел. Это устраняет необходимость в пустых списках особого случая. - person Useless; 04.08.2021
comment
И вы также можете использовать трюк с указателем на указатель, чтобы абстрагироваться от разницы в именах между head и любым другим указателем next на исключить необходимость специальных тестов. - person user4581301; 04.08.2021