首页 > 解决方案 > 使用指针的动态 LinkedList 的 push() 和 pop() 方法的 C++ 问题

问题描述

首先,我想在不使用 STL 的情况下创建一个带有指针的动态 LinkedList。这是一个了解指针如何在 C++ 中工作的练习。

我的问题是我的push()方法没有像我期望的那样创建 FifoElement。当我运行程序时,在我使用该pop()方法后它什么也没显示。我的一个例子main如下。

要将push新对象添加到列表中,我正在重载<<operator并且要从列表中弹出第一个元素,我正在重载>>operator

我的两门课是FifoFifoElement

先进先出:

template <class T>
class Fifo
{
    public:
        Fifo();

        void push(const T&);
        T pop();

        Fifo& operator<<(const T&);
        Fifo& operator>>(T&);


    private:
        FifoElement<T> *top;
};

先进先出元素:

template <class T>
class Fifo;

template<class T>
class FifoElement
{
    friend class Fifo<T>;

    public:
        FifoElement();

    private:
        T value;
        FifoElement<T> *next;
};

push 方法的代码片段:

...
template <class T>
void Fifo<T>::push(const T& val){
    //creates new Element
    FifoElement<T> *newElem = new FifoElement<T>(); //<= I think my problem is here but I am not sure..

    //inserts new value into Element
    newElem->value = val;

    //If Fifo/List is empty: Element is top...
    if(top == nullptr){
        top = newElem; //...füge am Anfang ein
        return;
    }

    //or:
    //when List has elements go to the end and then insert element at the end
    FifoElement<T> *tmpElem = top;
    while(tmpElem->next != nullptr){
        tmpElem = tmpElem->next;
        cout << tmpElem << endl;
    }
    //set new Element as next of the last element in the list 
    tmpElem->next = newElem;
}

template <class T>
Fifo<T>& Fifo<T>::operator<<(const T& val){
    push(val);
    return *this;
}
...

和 pop() 方法部分:

...
template <class T>
T Fifo<T>::pop(){
    //should read the first element of the list and delete it...
    FifoElement<T> *tmpElem = nullptr;
    FifoElement<T> *returnElem = nullptr;

    //if top is empty it means that the list is empty...
    if(top == nullptr){
        cout << "Liste ist leer!" << endl;
        returnElem = 0;
        return returnElem->value;
    }
    //the new element is the new top
    else if(top->next != nullptr){
        top = top->next;
        returnElem = tmpElem;
        //hier wird Element gelöscht!
        delete tmpElem;
        tmpElem = nullptr;
        //
        return returnElem->value;

    }

    //if only top exists then return it and delete it after that
    else{
        delete top;
        top = nullptr;
        returnElem = tmpElem;
        delete tmpElem;
        tmpElem = nullptr;
        return returnElem->value;
    }
}

template <class T>
Fifo<T>& Fifo<T>::operator>>(T& val){
    pop();
    return *this;
}
...

我的主要例子是这样的:

    ...
    int main() {
    Fifo<string> test;
    string ex = "Hey stackoverflow whatsup? :)";
    string ex2 = "can anyone help me?";
    test << ex;
    test << ex2
    test.pop(); //output here should be: "Hey, stackoverflow whatsup? :)"
    test.pop(); //output here should be: "can anyone help me?"
    ...
    return 0;
}

我希望我没有忘记任何事情。如果有人可以帮助我,那就太好了。我从 3 天开始就坐在那个程序上 :(

标签: c++pointersdynamiclinked-list

解决方案


您的pop方法太复杂并且包含错​​误,尤其是在内存处理方面。做类似的事情

returnElem = tmpElem;
delete tmpElem; 

是错误的,因为returnElem您没有创建 的副本,FifoElement<T>并且两个指针都指向同一个元素,因此只是变成了一个悬空指针。我把它改写为

template <class T>
T Fifo<T>::pop(){
    T value;
    if( top ){
        auto const old = top;
        top = top->next;
        value = old->value;  
        delete old;
    } else {
        cerr << "error - queue empty";
    }
    return value;
}

通过该更改,您的示例代码可以正常工作。我没有检查它是否有其他错误。请参阅此处的工作示例


推荐阅读