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

C++ 堆栈/队列中的内存泄漏c++;,c++,memory-leaks,stack,C++,Memory Leaks,Stack,我有一个任务,使用列表编写Stacks类,使用两个堆栈编写Queue类。我已经完成了任务,但运行valgrind时发现以下代码中存在内存泄漏: T Stack<T>::pop() { T *n = new T; *n = myStack.front(); myStack.pop_front(); return *n; } T堆栈::pop() { T*n=新的T; *n=myStack.front(); myStack.pop_front(); 返回

我有一个任务,使用列表编写Stacks类,使用两个堆栈编写Queue类。我已经完成了任务,但运行valgrind时发现以下代码中存在内存泄漏:

T Stack<T>::pop()
{
    T *n = new T;
    *n = myStack.front();
    myStack.pop_front();
    return *n;
}
T堆栈::pop()
{
T*n=新的T;
*n=myStack.front();
myStack.pop_front();
返回*n;
}

我无法在返回指针后删除它,因此我不确定如何修复它。提前谢谢。

你应该用

T n = myStack.front();

复制一份,然后清除前弹出窗口内的内存(如果有)

    T Stack<T>::pop()
    {
        T ret = myStack.front();
        myStack.pop_front();        
        return ret;
    }
T堆栈::pop()
{
T ret=myStack.front();
myStack.pop_front();
返回ret;
}

为什么您甚至需要使用新的?您可以制作堆栈顶值的副本,如下所示:

T Stack<T>::pop()
{
    T n = myStack.front();
    myStack.pop_front();
    return n;
}
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...
} 
T堆栈::pop()
{
T n=myStack.front();
myStack.pop_front();
返回n;
}

因此,没有分配,也没有泄漏

在你的位置上,我会停止使用原始指针,改为共享指针。是更安全的。

您得到了多个答案,给出了正确的代码,但您现有代码出错的原因如下:

T Stack<T>::pop()
{
    T n = myStack.front();
    myStack.pop_front();
    return n;
}
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...
} 
T堆栈::pop()
{
T*n=new T;//分配动态内存
*n=myStack.front();//对T的引用从front()复制到分配的T对象
myStack.pop_front();//删除堆栈中的T
return*n;//将分配的T对象复制到返回值
//指针变量超出范围,地址不存在存储位置,
//这就是泄漏发生的地方。。。
} 
T*n=新的T;
您正在使用new创建T,而不是使用它。这就是问题所在。

复制语义是C++最大的优点之一,因为你可以把编译器和类型T的作者归咎于:

T Stack<T>::pop() // may throw
{
    T ret = myStack.front();
    myStack.pop_front();
    return ret;
}

这为你提供了一个在清理过程中清理堆栈的方法,而不会抛出异常(C++中的析构函数是按惯例(不是标准)禁止的。

我实际上尝试过,但当时不起作用。可能是粗心和打字错误。不过现在可以了,谢谢大家的帮助!请注意,只有当move构造
T
是无抛出操作时,这才是强异常安全的。如果它可以抛出(或者如果
T
只有一个抛出复制构造函数),那么如果复制到返回值失败,您可能会丢失
T
中的数据。如果希望此操作为无抛出(对于合理的
T
),则将第一行更改为
tn{std::move(myStack.front())}