Конструктор копирования для двусвязного списка, проблема с инициализацией головы

Я пытаюсь написать конструктор копирования для шаблонного списка с двойной связью... Вот что у меня есть до сих пор:

// Copy Constructor
template <typename Item>
LinkedList<Item>::LinkedList(const LinkedList<Item> &s){
    // Create an iterator for the other list
    ListNode<Item> *node = s.head;
    // Create a reference to use as an iterator for the new list
    // Set it to the address of head of the new list
    ListNode<Item> **curr_node = &head;
    // Create a placeholder for the address of the previous node
    ListNode<Item> *prev_node = NULL;
    while(node != NULL){
            *curr_node = new ListNode<Item>;
            // If a prev_node address has been saved, initialize the new node's prev value
            // If a prev_node hasn't been saved yet, this means it is the head and prev should
            // be initialized to NULL 
            (*curr_node)->prev = prev_node;
            // Set the new node data fields to that of the node in the other list
            (*curr_node)->data = node->data;

            // -------- Set up for next iteration ------- 
            // Save the address of the current node to be used in the next node's prev_node 
            prev_node = *curr_node;
            // Set the curr_node pointer to the address of the next node in the new list 
            curr_node = &((*curr_node)->next);
            // Set the node pointer to the next node in other list
            node = node->next;
    }
    // Set the tail after all the nodes have been copied
    tail = prev_node;
}

Когда я вызываю этот код в своем тестере:

LinkedList<int> ll;
ll.insert_back(5); 
ll.insert_back(10);
ll.insert_back(15);
LinkedList<int> ll1 = ll;
cout << "Printing contents of copied list: "; ll1.print();

Я получаю эту ошибку в valgrind:

Contents of list to be copied: [5] -> [10] -> [15]
==4624== Conditional jump or move depends on uninitialised value(s)
==4624==    at 0x401077: LinkedList<int>::print() (LinkedList.cc:159)
==4624==    by 0x400D7B: main (tester.cpp:54)
==4624== 
==4624== Conditional jump or move depends on uninitialised value(s)
==4624==    at 0x40109E: LinkedList<int>::print() (LinkedList.cc:155)
==4624==    by 0x400D7B: main (tester.cpp:54)

Строки 153, 155, 159 моей функции print():

153: ListNode<Item> *end = head;
155: while(end != NULL){
159: if(end->next != NULL)

Итак, я делаю вывод, что end никогда не инициализируется, что означает, что head имеет значение NULL или установлено какое-то нежелательное значение... У кого-нибудь есть какие-нибудь мысли по этому поводу? Где я ошибаюсь?


person Riptyde4    schedule 21.10.2013    source источник


Ответы (1)


Кажется, вы хотели бы заменить строку

curr_node = &((*curr_node)->next);

с

*curr_node = &(node->next);

так как curr_node было установлено на new ListNode<Item> ранее внутри цикла while.

Просто любопытно, почему curr_node является указателем на указатель на узел?

person Mike    schedule 22.10.2013
comment
Что я пытаюсь сделать, так это установить curr_node равным адресу, на который установлено поле next текущего узла, чтобы я мог инициализировать его значением следующего узла другого списка. Установка *curr_node = &(node-›next) будет равна адресу узла списка, который я пытаюсь скопировать в новый список. - person Riptyde4; 22.10.2013
comment
curr_node = &((*curr_node)-›next) устанавливает curr_node равным адресу следующего узла текущего узла. Разыменование, позволяющее инициализировать следующее значение в списке. Я не знаю лучшего способа сделать это. - person Riptyde4; 22.10.2013
comment
Когда вы устанавливаете *curr_node = new ListNode<Item>;, вы вызываете конструктор по умолчанию для ListNode<Item>, а (*curr_node)->next инициализируется тем, что помещает туда конструктор для ListNode<Item>. Скорее всего, он указывает на NULL, но может быть неинициализирован. Как выглядит конструктор? - person Mike; 22.10.2013
comment
Он инициализирует next и prev нулем. - person Riptyde4; 23.10.2013