我正在编写自己的堆栈来练习语言和练习指针。我使用链表来表示堆栈而不是数组。推送操作只是将顶级节点值分配给每个节点,我无法弄清楚原因,我尝试编写一个赋值运算符,但它没有做任何事情。
template <class T>
void stack<T>::push(T data) {
//Operation to preform if the stack is empty.
//Root element is popped off last (First in, Last out)
if ( empty() ) {
root_node = new node;
root_node->node_data = data;
root_node->next = nullptr;
elements++;
}
//Operation to preform if stack is not empty.
//Elements inserted into stack with dynamic allocation.
else {
node *new_node = new node;
/* PROBLEM AREA */
new_node = root_node;
root_node->next = new_node;
root_node->node_data = data;
elements++;
}
这是节点结构
struct node { //Definition of node structure with constructor and destructor
T node_data;
node *next;
//default ctor
node() { next = nullptr; }
//default dtor
~node() { delete root_node; }
node operator=(const node &rhs) {
if ( this != &rhs) {
this->next = rhs->next;
this->node_data = rhs->node_data;
}
return *this;
}
};
按下10,20,40,30并弹出它们并调用top()
时的输出Top element 30
Current Top Element: 30 size of stack 3
Current Top Element: 30 size of stack 2
Current Top Element: 30 size of stack 1
答案 0 :(得分:1)
重载的operator=
是错误的。你有:
node operator=(const node &rhs) {
因此它按值返回副本。你没有定义一个拷贝构造函数,所以这将是一个“浅拷贝”,这将导致问题。
定义operator=
的常用方法是
node& operator=(const node &rhs) {
然而,这个函数内部的逻辑也没有意义:
if ( this != &rhs) {
this->next = rhs->next;
this->node_data = rhs->node_data;
}
现在您将有2个节点都指向相同的next
。所以你不再有一个列表,你有一些颠倒的树。
您应该实现或delete
/ private
您的拷贝构造函数,以消除意外浅拷贝发生的可能性。
另一个重要问题是:
node *new_node = new node;
new_node = root_node;
您制作了new node
,但随后您立即泄漏了内存,并将new_node
指向root_node
。根据你的描述,我怀疑你的意思是:
*new_node = *root_node;
表示new_node->operator=(*root_node);
调用您的operator=
函数。
总而言之,整个事情是如此混乱,而不是你可能从头开始重做它。我建议将代码分为两部分:
单独编写链接列表并检查它是否有效。 (这应该是一个班级)
完成后,您就可以在链表上执行堆栈实现。
答案 1 :(得分:0)
您在错误的顺序中执行else部分(您的问题所在)的分配。第二个语句立即破坏了新分配的节点。你应该拥有的是:
node *new_node = new node;
new_node->node_data = data;
new_node->next = root_node->next;
root_node = new_node;
elements++;