【问题标题】:Stack push operation implementation not working堆栈推送操作实现不起作用
【发布时间】:2014-05-26 23:54:25
【问题描述】:

我正在编写自己的堆栈来练习语言和练习指针。我使用链表来表示堆栈而不是数组。推送操作只是将顶部节点的值分配给每个节点,我不知道为什么,我尝试编写一个赋值运算符但它没有做任何事情。

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

【问题讨论】:

  • '这是我得到的输出 If ...' 嗯嗯什么?我找不到任何输出样本? (正确格式化代码避免任何滚动条,也可能有助于提高可读性!!)
  • new_node = root_node; 你刚刚分配的new node 现在永远丢失了。
  • 感谢您的建议。已编辑。
  • 您的root_node 永远不会改变,但root_node-&gt;node_data = data; 会不断改变数据
  • @Revoo 您将一个新节点分配给new_node,然后在下一行您将root_node 分配给new_node,没有其他内容指向新节点,因此它不能再已检索。

标签: c++ pointers stack implementation


【解决方案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-&gt;operator=(*root_node); 调用你的operator= 函数。


总而言之,整个事情是如此混乱,而不是您最好从头开始重做。我建议将您的代码分成两部分:

  • 链表
  • 堆栈逻辑

自行编写链表并检查它是否有效。 (这应该是一个类)

完成后,您就可以在链表的顶部执行堆栈实现了。

【讨论】:

  • 很好的答案!我忽略了我在这里使用指针而不是节点对象的事实。我假设语句 *new_node = *root_node 取消引用指针并将节点值相互分配?
  • 是的,它就是这么做的。如果您分配指针,则意味着使一个指针指向另一个指针所指向的内容;但如果你分配非指针对象,那么它会调用目标的operator=
【解决方案2】:

你在 else 部分(你的问题所在)以错误的顺序做作业。第二条语句立即破坏了新分配的节点。你应该拥有的是:

node *new_node = new node;
new_node->node_data = data;
new_node->next = root_node->next;
root_node = new_node;
elements++;

【讨论】:

  • 段错误来自重载的赋值运算符(如@matt-mcnabb 的回答中所述。
猜你喜欢
  • 2013-03-02
  • 2015-08-03
  • 1970-01-01
  • 1970-01-01
  • 2020-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-12
相关资源
最近更新 更多