我在这里正确管理了内存吗? (简单的C ++堆栈)

时间:2010-08-28 23:55:46

标签: c++ memory-management

我是一个动态分配内存的完整菜鸟。这会有内存泄漏或任何其他内存问题吗?

#include <iostream.h>

template <class T> class stack
{
         struct node
         {
                T value;
                node* next;
         };

         public:
                stack()
                {
                       size = 0;
                }

                ~stack()
                {
                       while(size > 0)
                       {
                           node *n = top->next;
                           delete top;
                           top = n;
                           size--;
                       }
                }

                void push(T value)
                {
                     node *n = new node;
                     n->value = value;

                     if(size == 0)
                     {
                          top = n;
                     }
                     else
                     {
                         n->next = top;
                         top = n;
                     }

                     size++;
                }

                T pop()
                {
                       if(size<1)
                       {
                            std::cerr<<"Stack underflow"<<endl;
                            exit(0);
                       }
                       else
                       {
                           node* n = top;
                           int val = n->value;
                           top = n->next;

                           delete n;
                           size--;

                           return val;
                       }
                }

                int getSize()
                {
                    return size;
                }

        private:
                int size;
                node *top;
};

4 个答案:

答案 0 :(得分:5)

我没有看到任何内存管理错误 - 但我确实看到了其他几种错误。例如,当T不是int时会发生什么? :)

此外,将堆栈实现为链接列表是浪费的,与deque使用的vectorstd::stack实现相比,执行效果相对较差。

答案 1 :(得分:5)

除了其他优秀的答案之外,还有一个注意事项:

if(size<1)
{
    std::cerr<<"Stack underflow"<<endl;
    exit(0);
}

我建议在这里考虑assert或例外情况。 exit有点鲁莽,但如果您决定exit,请不要退出0:这通常表示成功,这是您在错误中想要的最后一件事。

答案 2 :(得分:3)

您错过了Stack的复制构造函数/赋值运算符。

当您创建Stack :: Node的对象时,您并不总是初始化下一个成员。为堆栈节点编写构造函数析构函数,其他一切都变得简单。

#include <iostream.h>

template <class T> class stack
{
         /*
          * The stack object contains a RAW pointer (top)
          * So when the object is copied with either copy constructor or
          * assignment operator when need to handle that fact. The simplist way
          * to handle is to make sure it can not happen. To do this make them
          * private (You do not need to define them as they can't be used).
          */
         Stack(Stack const&);            // Not defined
         Stack operator=)(Stack const&); // Not defined

         struct Node
         {
                // Initialize Node
                Node(Node* n, T v)
                  :next(v)
                  ,value(v)
                {}
                ~Node() // Destroy whole chain.
                {    delete next;
                }
                // Data
                T     value;
                Node* next;
         };

         public:
                stack()
                   :size(0)
                   ,top(NULL)
                {}

                ~stack()
                {
                    /// destructor is now simple
                    delete top;
                }

                void push(T value)
                {
                   /// As is the push.
                     top  = new node(top, value);
                     ++size;
                }

                T pop()
                {
                    /// The pop is just the same.
                       if(size<1)
                       {
                            std::cerr<<"Stack underflow"<<endl;
                            exit(0);
                       }
                       else
                       {
                           node* n   = top;
                           T     val = n->value;
                           top       = n->next;
                           n->next   = NULL;    // Set to NULL to stop the delete chaining.

                           delete n;
                           size--;

                           return val;
                       }
                }

                // Make this method a constant.
                // As it does not change the object.
                int getSize() const
                {
                    return size;
                }

        private:
                int size;
                node *top;
};

答案 3 :(得分:0)

其他一些提示:

而不是在内部模拟堆栈只需使用一个普通列表,其中有一个指向列表的第一个和最后一个元素的指针,只要你提供推/弹功能,就不需要在内部模仿堆栈。 / p>

我也会完全跳过'size'成员,而只是计算列表中的节点。这样您就不需要保持大小计数器和列表同步。只需确保将指针初始化为NULL即可。计算大小会看起来像:

for(Node* p=first; p!=NULL; p=p->next) ++size;