0

我不确定我是否应该开始一个新线程,但由于编辑我以前的问题会涉及大量重新排列代码,我认为一个新线程是最好的。

template <class T>
class node {
public:
    T value;
    node<T> *next;
    node<T> *previous;  
};

template <class T>
class my_list {
public:
    node<T> *first;
    node<T> *last;
    my_list(){
        first = NULL;
        last = NULL;
    }
    ~my_list(){
    }
    void push_back(T val);
    void push_front(T val);
    void pop_back();
    void pop_front();
    T front();
    T back();
};

以上是班级布局。下面是 pop_back() 方法,它应该删除列表中的最后一个节点。我无法让它工作。它运行但似乎没有重新分配最后一个节点,因为当我调用 T back() 函数时它返回一个随机值。

template <class T>
void my_list<T>::pop_back(){
    node<T> oldlast = *this->last;
    node<T> newlast = *oldlast.previous;
    cout << newlast.value << endl;
    newlast.next = NULL;
    this->last = this->last->previous;
}  


template <class T>
void my_list<T>::push_back(T val){
    if (this->first == NULL) {
    node<T> newnode;
    newnode.value = val;
    newnode.next = NULL;
    newnode.previous = NULL;
    this->first = &newnode;
    this->last = &newnode;
} else {
    node<T> current = *this->last;
    node<T> newnode;
    newnode.value = val;
    newnode.previous = &current;
    newnode.next = NULL;
    current.next = &newnode;
    this->last = &newnode;
}
}

template <class T>
void my_list<T>::push_front(T val){
if (this->first == NULL) {
    node<T> newnode;
    newnode.value = val;
    newnode.next = NULL;
    newnode.previous = NULL;
    this->first = &newnode;
    this->last = &newnode;
} else {
    node<T> current = *this->first;
    node<T> newnode;
    newnode.value = val;
    newnode.previous = NULL;
    newnode.next = &current;
    current.previous = &newnode;
    this->first = &newnode;
}

}

4

1 回答 1

1

问题是您正在制作局部node<T>变量并为它们分配指针。当函数结束时,这些局部变量会超出范围,并且您的指针不再有效。在 的情况下pop_back,您使用以下行复制列表中的最后两个元素

node<T> oldlast = *this->last;
node<T> newlast = *oldlast.previous;

因此,当您使用该行修改newlast's next 指针时

newlast.next = NULL;

您实际上是在修改副本,而不是实际元素。因此,与其复制对象自身,不如复制指向对象的指针,然后根据需要更改.->

template <class T>
void my_list<T>::pop_back(){
    node<T> *oldlast = last;
    node<T> *newlast = oldlast->previous;
    cout << newlast->value << endl;
    newlast->next = NULL;
    last = newlast;
    delete oldlast;
}

因为push_backand push_front,newnode是一个局部变量,所以在函数结束时被销毁。相反,您必须动态分配它new(更好的是使用诸如unique_ptr之类的智能指针,但我假设这是您可能无法使用的课程)。你应该newnode像这样创建

node<T>* newnode = new node<T>;

由于newnode是一个指针,因此您必须再次将所有更改.->. 此外,由于您使用 分配此节点new,因此您必须取消分配它delete以避免内存泄漏。因此,在您的pop_back函数中,您必须删除要从列表(delete oldlast;行)中删除的元素。

于 2013-05-06T17:36:48.653 回答