C++ push() 和 pop() 方法使用指针的动态 LinkedList 的问题

C++ problem with push() and pop() methods for dynamic LinkedList using pointers

本文关键字:指针 问题 动态 LinkedList 方法 push pop C++      更新时间:2023-10-16

首先,我想创建一个带有指针的动态链接列表,而无需使用STL。这是一个了解指针在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;
};

推送方法的代码片段:

...
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 天开始就坐在那个程序上:(

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

通过该更改,您的示例代码就可以工作了。我没有检查它是否有其他错误。在此处查看工作示例