我是一个动态分配内存的完整菜鸟。这会有内存泄漏或任何其他内存问题吗?
#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;
};
答案 0 :(得分:5)
我没有看到任何内存管理错误 - 但我确实看到了其他几种错误。例如,当T
不是int
时会发生什么? :)
此外,将堆栈实现为链接列表是浪费的,与deque
使用的vector
或std::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;