我有一个使用list和Queue类编写Stacks类的任务,使用两个Stacks。我已完成任务,但运行valgrind我发现在以下代码中有内存泄漏:
T Stack<T>::pop()
{
T *n = new T;
*n = myStack.front();
myStack.pop_front();
return *n;
}
我退回后无法删除指针,所以我不知道如何修复它。提前谢谢。
答案 0 :(得分:4)
为什么你甚至需要使用新的?您可以像这样复制堆栈的最高值:
T Stack<T>::pop()
{
T n = myStack.front();
myStack.pop_front();
return n;
}
所以没有分配,也没有泄漏;
答案 1 :(得分:3)
制作副本,然后清除内存(如果内部有pop_front)。
T Stack<T>::pop()
{
T ret = myStack.front();
myStack.pop_front();
return ret;
}
答案 2 :(得分:0)
你应该使用
T n = myStack.front();
答案 3 :(得分:0)
在你的位置,我会停止使用原始指针并更改为shared_ptr。是更安全。
答案 4 :(得分:0)
你有多个答案给出正确的代码,但你现有的代码错误的原因是这样的:
T Stack<T>::pop()
{
T *n = new T; // allocates dynamic memory
*n = myStack.front(); // reference to T from front() copied to allocated T object
myStack.pop_front(); // removes the T in the stack
return *n; // copies your allocated T object to the return value
// your pointer variable goes out of scope, that address is stored nowhere,
// this is where the leak occurs...
}
答案 5 :(得分:0)
T * n =新T; 您正在使用new创建T而不使用它。这就是问题。
答案 6 :(得分:0)
复制语义是C ++最大的优势之一,因为你可以把编译器和'T'类型的作者归咎于:
T Stack<T>::pop() // may throw
{
T ret = myStack.front();
myStack.pop_front();
return ret;
}
请注意,这是pop-function的次理想形式。复制时,可能会抛出异常,这使得实现异常安全的pop函数基本上是不可能的。
容器std::stack<>
通过返回类型void
来解决:
void Stack<T>::pop() // no-throw [if T is written by a sane coder]
{
myStack.pop_front();
}
T Stack<T>::back() // may throw
{
return myStack.front();
}
这为你提供了一个在销毁时清理你的堆栈而不会抛出异常的意思(按照惯例(不按标准),在C ++中抛出析构函数是禁止的。)