【问题标题】:Why am I getting bad_alloc? Implementing a stack c++为什么我得到 bad_alloc?实现堆栈 C++
【发布时间】:2019-05-02 19:52:53
【问题描述】:

我正在尝试在 C++ 中实现我自己的堆栈,但是当我尝试使用 pop() 方法时,我一直收到此错误,我正在尝试做的是:

  1. 将元素从顶部保存到名为“res”的变量中。
  2. 从节点类中获取对下一个元素的引用并将其设置为顶部。
  3. 大小--
  4. 返回变量“res”。

如果您能帮助我,我将不胜感激。谢谢!

节点类:

template<class T>
class Node {
private:
    Node<T>* next;
    T element;

public:
    Node();

    Node(const Node& orig);

    ~Node();

    void setElement(T el);

    T getElement();

    Node<T>* getNext();

    void setNext(Node<T>* ne);
};

堆栈类:

#include "EmptyStackException.cpp"
#include "Node.cpp"
#include <iostream>

using namespace std;

template<class T>
class LinkedStack {
private:
    int siz;
    Node<T>* first;

public:
    LinkedStack();

    ~LinkedStack();

    int size();

    bool isEmpty();

    void push(T e);

    T top();

    T pop();
};

template<class T>
void LinkedStack<T>::push(T e) {
    Node<T> node = Node<T>();
    node.setNext(first);
    node.setElement(e);
    first = &node;
    siz++;
}

template<class T>
T LinkedStack<T>::pop() {
    T res = first->getElement();
    first = *(first->getNext());
    siz--;
}

【问题讨论】:

  • rule of 3/5/0 表示NodeLinkedStack 需要赋值运算符,LinkedStack 还需要一个复制构造函数。此外,许多现有的构造函数和析构函数并没有做他们应该做的事情。
  • 您不能存储&amp; 的结果以供以后使用。您需要动态分配。
  • first = &amp;node; 接受一个指向本地对象的指针,当您的函数返回时,该指针将不复存在。您将需要使用某种形式的动态分配。
  • 令人惊讶的是,我经常看到一个关于存储指向局部变量的指针引起的问题的问题。这种明显错误的模式是否在某处被教授?

标签: c++ c++11 pointers stack bad-alloc


【解决方案1】:
template<class T>
void LinkedStack<T>::push(T e) {
    Node<T> node = Node<T>();
    node.setNext(first);
    node.setElement(e);
    first = &node;
    siz++;
}

由于node是这个函数的本地对象,所以这个函数一结束,它就被销毁。但是,first 包含指向它的指针。所以当这个函数返回时,first 包含一个指向不再存在的对象的指针。你可能想要这个:

template<class T>
void LinkedStack<T>::push(T e) {
    Node<T>* node = new Node<T>();
    node->setNext(first);
    node->setElement(e);
    first = node;
    siz++;
}

现在,当此函数返回时,node 仍然不复存在。但是first 不包含指向node 的指针,它包含node 的值——一个指向动态分配对象的指针。

请注意,您必须以某种方式管理该对象的生命周期。理想情况下,您不会使用原始指针,这样您就没有这种负担。

【讨论】:

  • @SantiagoPardal 不,这是不对的。在这两种情况下,node 都是在函数终止时被销毁的本地对象。但在前一种情况下,node 是您存储指向的 Node。在后一种情况下,node 只是函数终止后不再需要的指针。如果您使用new 创建一个对象,它会一直存在,直到您对其调用delete
  • @SantiagoPardal 您的代码中可能还有其他更细微的错误,但在修复明显的错误之前,您将无法找到细微的错误。正确管理集合中对象的生命周期至关重要。为什么不使用unique_ptr 之类的东西来减轻你的负担?
  • @DavidSchwarz 谢谢,我会试试的。
  • @DavidSchwartz 这可能是课堂作业的一部分,其中可能不允许使用 c++ 11 智能指针管理指针。在课堂之外,我完全同意,如果不是特别需要,为什么还要费心让自己陷入手动内存管理的境地?
猜你喜欢
  • 1970-01-01
  • 2018-06-25
  • 1970-01-01
  • 2010-11-27
  • 1970-01-01
  • 2021-04-07
  • 2021-06-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多