Путаница с двусвязным списком

Я создал двусвязный список и 2 функции. Первая функция печатает список от начала до конца, а вторая функция печатает список от начала до конца. Во второй функции я устанавливаю первый узел->предыдущий в NULL, но

  • Я не понимаю, почему первая функция на самом деле работает, потому что я никогда не устанавливал следующий указатель последнего узла в NULL, поэтому, на мой взгляд, это должно создать бесконечный цикл.

Вот код:

#include <iostream>

using namespace std;

class LinkedList
{
    struct Node 
    {
        int data;
        Node * next;
        Node * prev;
    };

    public:
           LinkedList    ( void );
      void AddToList     ( int val );
      void FrontToBack   ( void ) const;
      void BackToFront   ( void ) const; 

    private:
        Node * head;
        Node * n;
        Node * tail;
};

LinkedList::LinkedList ( void )
{
    head = NULL;
    n = NULL;
    tail = NULL;
}

void LinkedList::AddToList ( int val )
{
    n = new Node ( );
    n -> data = val;
    if ( head == NULL )
    {
        n -> prev = NULL;
        head = n;
        tail = n;
    }
    else
    {
        n -> prev = tail;
        tail -> next = n;
        tail = n;
    }
}

void LinkedList::FrontToBack ( void ) const
{
    Node * tmp = head;
    int size = 0;

    cout << "Printing list from head to tail:" << endl; 

    while ( tmp != NULL )
    {
        if ( ! size )
        {
            cout << tmp -> data;
            tmp = tmp -> next;
        }
        else
        {
            cout << " " << tmp -> data;
            tmp = tmp -> next;
        }
        ++ size;
    }

    cout << endl;
}

void LinkedList::BackToFront ( void ) const
{
    Node * tmp = tail;
    int size = 0;

    cout << "Printing list from tail to head:" << endl;

    while ( tmp != NULL )
    {
        if ( ! size )
        {
            cout << tmp -> data;
            tmp = tmp -> prev;
        }
        else
        {
            cout << " " << tmp -> data;
            tmp = tmp -> prev;
        }
        ++ size;
    }

    cout << endl;
}



int main ( void )
{

    LinkedList list;

    list.AddToList( 1 );
    list.AddToList( 2 );
    list.AddToList( 3 );
    list.AddToList( 4 );
    list.AddToList( 5 );
    list.AddToList( 6 );

    list.FrontToBack( );
    list.BackToFront( );

    return 0;

}

person kvway    schedule 13.03.2016    source источник
comment
У вас просто неопределенное поведение при доступе к неинициализированным переменным-членам Node, может случиться что угодно, включая, казалось бы, правильное поведение.   -  person πάντα ῥεῖ    schedule 13.03.2016
comment
Возможно, значение по умолчанию Node::next равно nullptr?   -  person Mr. Anderson    schedule 13.03.2016
comment
@πάνταῥεῖ, так что мне даже не нужно устанавливать n -> prev = NULL; в первом узле?   -  person kvway    schedule 13.03.2016
comment
@kvway Нет, вы всегда несете ответственность за правильную инициализацию всех переменных-членов. Я сказал, что все может случиться, нет никакой гарантии, что он будет вести себя так, как вы наблюдаете.   -  person πάντα ῥεῖ    schedule 13.03.2016


Ответы (1)


  • Я не понимаю, почему первая функция на самом деле работает, потому что я никогда не устанавливал следующий указатель последнего узла в NULL, поэтому, на мой взгляд, это должно создать бесконечный цикл.

Указатели next и prev для struct Node никогда не инициализируются, поэтому доступ к ним и разыменование их — поведение undefined. Это означает, что вы не можете ожидать какого-либо конкретного поведения, такого как бесконечный цикл.

Чтобы обеспечить определенное поведение, просто по умолчанию инициализируйте указатели в вашей структуре Node:

struct Node 
{
    int data;
    Node * next;
    Node * prev;

    Node() : next(nullptr), prev(nullptr) {} // <<<<<<<<<<<<<<<<<<<
};
person πάντα ῥεῖ    schedule 13.03.2016