2012-10-12 140 views
3

我有一個任務,使用一個列表和一個使用兩個堆棧的Queue類來編寫Stacks類。我已經完成了任務,但在運行Valgrind的,我覺得,我在下面的代碼中的內存泄漏:堆棧/隊列中的內存泄漏C++

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

我不能刪除指針後,我回吧,所以我不知道如何修理它。提前致謝。

回答

0

你應該已經相當使用

T n = myStack.front(); 
3

製作副本,然後清除如果有的話裏面pop_front內存。

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

爲什麼你甚至需要使用新的?你可以像這樣做一個堆棧的最高值的副本:

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

所以沒有分配和沒有泄漏;

+0

我實際上已經嘗試過這種方法,但當時並不奏效。可能是粗心大意和錯誤的東西。儘管工作,但感謝大家的幫助! – user1740222

+1

請注意,如果移動構造「T」是一個無投擲操作,則這只是強烈異常安全的。如果它可以拋出(或者'T'只有一個拋出的複製構造函數),那麼如果複製到返回值失敗,則可能會丟失'T'中的數據。如果你希望這個操作是無拋出的(對於合理的'T'),那麼把第一行改成'T n {std :: move(myStack.front())};' – Mankarse

0

在你的地方,我會停止使用原始指針並更改爲shared_ptr。是更安全。

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... 
} 
0

T * N =新款T; 你正在使用new創建T而不使用它。那就是問題所在。

0

複製語義是C++的最大優勢之一,因爲你可以把編譯器和類型'T'的作者指責:

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

但請注意,這是一個子理想形態一個流行功能。複製後,可能會拋出異常,這使得實現一個異常安全的彈出功能基本上是不可能的。

容器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投擲析構函數++是,按照慣例(不標準),禁止)。