【问题标题】:C++ problem with push() and pop() methods for dynamic LinkedList using pointers使用指针的动态 LinkedList 的 push() 和 pop() 方法的 C++ 问题
【发布时间】:2020-03-27 10:10:42
【问题描述】:

首先,我想在不使用 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;
};

FifoElement:

template <class T>
class Fifo;

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

    public:
        FifoElement();

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

push方法的代码sn-p:

...
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 天就开始参加那个节目了 :(

【问题讨论】:

  • 你的结论是错误的。删除它们,然后 debug 你的 pop 方法,密切注意你的局部变量的值。
  • pop 方法完全没有意义。 returnElem 从未设置为top,它被设置为tmpElem,并且两者都是nullptr。然后你在设置returnElem=tmpElem 之后删除tmpElem,这也将删除returnElem 的内容,因为你所做的只是一个浅拷贝(只是设置指针)。

标签: c++ pointers dynamic linked-list


【解决方案1】:

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

returnElem = tmpElem;
delete tmpElem; 

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

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;
}

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

【讨论】:

  • 他不能使用STL,我认为其中包括std::unique_ptr
  • 是的,现在它符合要求。 OP 写的 pop 方法让我笑了。这是迄今为止我见过的最奇怪的流行音乐。
  • 一件小事,也许是吹毛求疵,但top = top.next; 应该足够了,不是吗?如果next == nullptr 会自动变为top = nullptr
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-16
  • 2021-10-12
  • 1970-01-01
  • 1970-01-01
  • 2021-12-06
相关资源
最近更新 更多