2013-07-28 44 views
-1

假設我們想用C++聲明一個函數,其中我聲明瞭一個局部變量int p=new int [10];,之後我做了一些操作,最後我做了一些操作,並且最後我用了return p;「新」會導致函數中的內存泄漏嗎?

正如我們常說的,如果我們使用new,我們必須delete。但我認爲在這種情況下,我們不應該刪除,對吧?否則,它根本無法返回p,對嗎?但是,我也在考慮在int main()中測試它時是否應該刪除該函數返回的項目。

+0

有沒有理由不能使用'vector '? –

+1

我問這個問題的關鍵是要弄清楚內存分配究竟如何工作 – Cancan

+0

@ CanCan,雖然我理解你的分配問題,但我想強調NicolBolas是正確的,通常返回矢量是最好的解決方案。 – tohava

回答

5

的規則是,每new必須有一個delete(併爲每一個new[]delete[]*),但它不一定是在同一範圍內。通常有函數動態創建一個對象並將該對象的所有權轉移給調用者。調用者然後將負責刪除內存。

話雖這麼說,你應該避免直接在你的代碼中調用newdelete,並喜歡使用那些安全(帶自動處理內存的你)其他結構。在你提到的特定情況下,用10個元素初始化的std::vector<int>與指針相比幾乎沒有開銷,並且確保只要對象被銷燬就釋放內存。

*根據您的實現,有可能是在那裏你new(或new[]),而不是刪除,如果內存是交給一個智能指針的情況。例如,在C++ 11你可以這樣做:

std::unique_ptr<int[]> f() { 
    std::unique_ptr<int[]> p(new int[10]); // new is unmatched 
    // ... 
    return p; 
} 

這是好的,因爲處理的指針std::unique_ptr確保它會調用delete[]內部,當它超出範圍(如果沒有移動到不同的智能指針)。

+0

我總是害怕使用向量或列表或其他STL的原因是我不知道它們是否支持自動轉換。例如,我聲明瞭一個像inputsomething(矢量 a)和delcare a這樣的函數作爲int a [10],它們會自動轉換嗎?或換句話說,如果我在函數中聲明瞭一個,我可以聲明任何其他類似的STL嗎? – Cancan

+1

@Cancan:不會,它不會從數組轉換爲vector,儘管使用'std :: vector'中提供的構造函數手動進行轉換非常簡單。另一方面,從'std :: vector'到一個指針,你可以傳遞'&v [0]'(即第一個元素的地址),因爲矢量保證了元素的連續性。另一個問題是你是否想要使用原始數組。如果'std :: vector'成爲* vocabulary *類型來處理元素序列,那麼所有的函數都會使用它,並且不需要任何轉換。 –

+0

哦,這也很酷,你能告訴我哪個構造函數是將普通數組轉換爲向量? – Cancan

0

使用數組完成程序時應該刪除。它不必處於相同的功能。

如果總是需要delete做函數結束時,它會得到自動添加(unique_ptr是一種方式告訴C++ 11自動免費的東西new當函數結束)

3

呼叫者需要要知道你退回了創建的東西new [],並在必要時致電delete []。在這樣的結構中有很多錯誤的可能性。更好地回報照顧自己記憶的東西,如std::vectorstd::unique_ptr

0

它們是從堆中分配的。所以你可以並且應該在函數外的任何地方刪除。

新建和刪除不使用堆棧。 malloc和free一樣。

0

您可以delete []p在新的範圍內它完成後返回它。然而,僅僅分配一個帶有new的內存並將所有權賦予另一個範圍並不是一個好習慣。您可以使用std::vectorsmart pointers