2016-12-31 131 views
2

總是刪除指針,即使它只是在函數調用堆棧? 功能堆棧發佈時不會消失嗎?即使在函數堆棧中,也必須刪除指針嗎?

// just Simple class 
class CSimple{ 
    int a; 
} 

// just simple function having pointer. 
void simpleFunc(){ 
    CSimple* cSimple = new CSimple(); 
    cSimple->a = 10; 
    //.. do sth 
    delete cSimple; // <<< Always, do I have to delete 'cSimple' to prevent the leak of memory? 
} 

void main(){ 
    for(int =0 ; i< 10 ; i++){ 
    simpleFunc(); 
    } 

} 
+1

1.是。無論內存泄漏源於何處,內存泄漏都是內存泄漏。 2.排序。指針是「釋放」的,指向的對象不是。 – owacoder

+1

'new'分配的所有內存必須使用'delete'釋放。 –

+3

'delete cSimple'不會刪除指針,指針會自動分配,並且在聲明它的範圍時將被釋放。但它會刪除動態分配的'CSimple'的新實例,當'cSimple'超出範圍時它將不會被釋放。只要你有一些方法來刪除你的每個'new CSimple();'實例(和),就不會有泄漏。 – George

回答

0

是的,您必須delete被指向的數據。

指針本身在堆棧上,不需要刪除。

你可以,但是,在堆棧上店鋪cSimple,那麼你不必把它刪除:

void simpleFunc(){ 
    CSimple cSimple; // no new 
    cSimple.a = 10; // "." instead of "->" 
    //.. do sth 
    // no deletion 
} 
2

函數棧發佈的時候?

確實,「CSimple * csimple」在函數返回時消失。

但是,指針和它所指向的內容之間存在很大差異。

當指針對象被銷燬時,指針所指向的任何內容都不會發生。這裏不僅有一個,而且有兩個對象:

  1. 指針。

  2. 它指的是什麼。

在這種情況下,指針指向的動態範圍內的對象是用new創建的。

這個對象不會發生任何事情,否則,所以你會泄漏內存。

因此,該對象需要爲delete d。

當你理解並完全圍繞這個概念包裝你的大腦後,下一步就是將你的C++書籍打開到討論std::unique_ptrstd::shared_ptr類的章節,這些類將爲你處理這些煩人的細節。你應該學習如何使用它們。現代C++代碼很少需要delete的東西;而是這些智能指針完成所有工作。

+0

更經常的是,不要使用任何原始指針或智能指針,而是使用'CSimple csimple;'將對象生存期直接綁定到作用域。 – user2357112

1

是的。

在範圍退出時(例如,當函數存在或塊{...}結束時),堆棧上創建的所有對象都將被銷燬,內存將被釋放。

這適用於你的情況,即。指針將被銷燬並且指針佔用的內存將被釋放。指針指向的對象不會被清除。

當處理多個流程路徑(if-else梯形圖,許多返回語句)和異常時,這是一個常見問題和噩夢。

爲了解決這個問題,我們採用兩個主要策略:

  1. RAII
  2. 智能指針(std::unique_ptrboost::scoped_ptr,傳統std::auto_ptr等)。

RAII - 沒有學術的考慮 - 只是在堆棧上創建對象,就像這樣:

{ 
    std::string s; 
    fancy_object obj; 
} 

當我們離開他的範圍,objs析構函數將被調用堆棧史稿平倉。編譯器確保所有流路都具有此功能,並且會爲我們保留正確的釋放順序。

如果您需要在堆上分配內存,使用new,請使用智能指針。

int foo() 
{ 
    std::unique_ptr<Object> o(new Object); 
    ... some more code ... 
    if(something) { return -1 } 
    ... some more code ... 
    if(something_else) { return -2 } 
    else { not yet } 
    return 0; 
} 

正如您所看到的,我們可以使用3「存在」離開範圍。通常情況下,您需要清除所有情況下的記憶,這很容易出現人爲錯誤。

我們沒有在所有3個手柄中手動清除對象,而是依靠堆棧上創建的對象的自動析構函數調用。編譯器會解決它。當我們離開示波器時,將調用std::unique_ptr析構函數,調用delete,Object

不要害怕智能poiners。他們不是「緩慢」,「膨脹」或其他廢話。智能poiners被設計爲沒有訪問開銷,增加額外的安全性。

非常類似的技術用於鎖。查看std::lock_guard課程。