堆栈/队列中的内存泄漏c ++

时间:2012-10-12 06:21:05

标签: c++ memory-leaks stack

我有一个使用list和Queue类编写Stacks类的任务,使用两个Stacks。我已完成任务,但运行valgrind我发现在以下代码中有内存泄漏:

T Stack<T>::pop()
{
    T *n = new T;
    *n = myStack.front();
    myStack.pop_front();
    return *n;
}

我退回后无法删除指针,所以我不知道如何修复它。提前谢谢。

7 个答案:

答案 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 ++中抛出析构函数是禁止的。)