2012-03-13 2 views
2

Я работаю над шаблоном, связанным с общим списком на C++, и у меня возникают проблемы с методом push(). Я думаю, что знаю проблему, но я не могу найти решение. Вот метод push, который у меня есть.Связанный список метод push

template <class T> void DLL<T>::pushFront(T value) { 
    Node<T> node(value); 
    temp = node; 
    temp->setPrev(*head); 
    temp->setNext(*(head->getNext())); 
    head->setNext(*temp); 
    temp->getNext()->setPrev(*temp);                                  
    this->length++;                                      
} 

После нажатия некоторых целых чисел в список, проходя по списку и распечатке результатов значения в печати от числа, которые кажутся случайным пространством в памяти. Я думаю, это связано с чем-то, связанным с тем, что переменная узла уничтожается после возврата функции push. Кто-нибудь знает, почему это не работает? Все функции setNext/Prev() и getNext/Prev() работают правильно в моих других тестах. Я в тупике ...

редактировать *

Переменные головы и температура являются Глобал типа Node < T> *

+0

Предполагается, что строка 3 должна быть temp = & node? – tmpearce

ответ

1

Вы должны использовать указатели для хранения узлов в списке.

Node<T> node(value); 
temp = node; 

После того, как этот код вышел из сферы действия, память, выделенная для «узла», будет освобождена, развращая связанный список. Используйте указатели вместо:

template <class T> void DLL<T>::pushFront(T value) { 
    Node<T> *node = new Node<T>(value); 
    node->setPrev(head); 
    node->setNext(head->getNext()); 
    head->setNext(node); 
    node->getNext()->setPrev(node); 
    this->length++; 
} 

Где ваш класс Node должен быть что-то вроде:

template<class T> class Node { 
public: 
    /* ... */ 
private: 
    Node<T> *next; 
    T data; 
}; 
+0

Даже при этом этот способ по-прежнему имеет те же результаты. Есть ли какой-то конкретный способ, которым мне нужно сохранить «новый Node (значение)» вживую? Это нормально, что он объявлен внутри метода, правильно? –

+0

Да, все в порядке. У вас, вероятно, проблема в структуре узла, трудно сказать, что это такое, поскольку вы только дали нам этот метод. – mfontanini

0

Прежде всего, head должен не быть глобальным - он должен быть членом DLL, так каждая dll (белая аббревиатура, IMO) имеет голову (и, вероятно, хвост).

Во-вторых, getnext, setnext, getprev и setprev кажутся мне 100% бессмысленной тратой времени. Вы ничего не получаете в процессе инкапсуляции или чтения, используя их вместо чтения/назначения переменных.

В-третьих, поскольку @fontanini уже указал, когда вы используете узел, вам нужно на самом деле выделить узел, а не пытаться повторно использовать один узел каждый раз.

В-четвертых, он смотрит на меня, как вы чрезмерно усложнять манипуляции указателя участие, вероятно, по крайней мере, частично из-за уродства/unreadability в getnext/setprev и т.д. Если у вас есть узел, сращивании его передняя часть связанного списка принимает только три операции (плюс приращение длины):

template <class T> 
void DLL<T>::pushFront(T value) { 
    node<T> *tmp = new node<T>(value); 
    tmp -> next = head; 
    tmp -> next -> prev = tmp; 
    head = tmp; 
    ++length; 
} 

Когда я сделал это, я нашел это немного проще, просто передать указатели на CTOR узла, хотя. В этом случае получается что-то вроде этого:

template <class T> 
void DLL<T>::pushFont(T value) { 
    // These parameters are value, prev, and next, respectively.        
    node<T> *tmp = new node<T>(value, NULL, head); 
    tmp->next->prev = tmp; 
    head = tmp; 
    ++length; 
} 
Смежные вопросы