2011-10-19 160 views
0

我是新來的C++。C++內存管理澄清

我有Rectangle類。當我創建了一個Rectangle對象是這樣的:

Rectangle R1(10,10,90,20); 
  • 不R1冷眼堆或疊?
  • 如果我使用new運算符創建它,只會在堆上?

(一般會是什麼,以C語言創建一個對象的正確方法+?)

據我瞭解,如果我沒有new創建它的對象位於堆棧上,並不需要被刪除在其生命週期結束時。如果做新

Rectangle* R = new Rectangle(1,1,1,1); 

它將被放置在堆上創建它,將需要使用delete被去分配。

+2

這是一個功課題嗎? – SingleNegationElimination

+0

必須有這個副本。 –

+0

@TokenMacGuy我在做家務時遇到了這個問題 這不是它的一部分,它更像是一個普遍的想法。 –

回答

4
Rectangle R1(10,10,90,20); 

這會創建一個具有「自動」持續時間的變量。當代碼流退出範圍時它會自動銷燬。如果它不在函數中,那意味着代碼的執行完成。通常(但不總是)它位於某種堆棧上。

Rectangle* R = new Rectangle(1,1,1,1); 
Rectangle* P(new Rectangle(1,1,1,1)); //rarely used 

這部分是混亂:變量R是具有自動持續時間(如上文)的指針。它指向具有「動態」持續時間的Rectangle。通常(但不總是)動態對象位於某種堆上。只有在您明確銷燬delete R;時,該矩形纔會被銷燬。這意味着如果功能結束並且沒有其他的R副本,則無法刪除,並且將保留在內存中,直到程序結束。這被稱爲內存泄漏。

在C++中,最好使用智能指針處理動態內存,如std::unique_ptr,這樣即使代碼崩潰,也不會意外忘記刪除它。

std::unique_ptr<Rectangle> R(new Rectangle(1,1,1,1)); 
+0

請注意,如果'Rectangle *'超出範圍(例如,函數調用返回)而沒有調用'delete R',則將創建內存泄漏。 –

+0

謝謝,我不知道如果我需要刪除R1 你已經說得很清楚,我沒有 謝謝你的洞察力:) –

+0

我澄清了指針和堆上的矩形之間的區別。我希望。 –

0
  1. R1與自動存儲持續時間創建。這意味着,在實踐中,它將被分配在一個堆疊狀結構中。它不必介意你,'堆棧'只是方便而且常見的。你必須撥打new(或malloc,如果你真的想出於某些愚蠢的原因......不要)動態分配內存。

  2. 見上。

  3. 是的,任何你new你必須delete。通常一個班級會爲你管理這個。以std::vector<T>爲例。您在堆棧上分配vector,但內部數據(即T的數組)是動態分配的。當vector超出範圍時,delete []是您在其析構函數中爲您動態分配的數組,允許您對基礎內存管理細節保持愉悅無知。

1

你說的很多東西都是實現細節或依賴於上下文。這樣考慮:

// file.cpp 

Rectangle r1(1,2,3,4); 

int main() 
{ 
    Rectangle r2 = r1; 
    Rectangle * r3 = new Rectangle(r1); 
} 

這裏r1具有靜態存儲靜態(=永久的)壽命,而r2具有自動存儲自動(=作用域)壽命。也就是,r1在程序開始時構造並在最後銷燬(在main返回後),而r2在聲明中構造並在其作用域的末尾(即本例中的函數體範圍)銷燬。

指針r3指向動態存儲動態(=手冊)壽命Rectangle對象。對象*r3new表達式中生效,並且只會在用戶請求時通過匹配的delete表達式(或者可能是手動析構函數調用)銷燬對象*r3。由於我們不摧毀它,所以這實際上是泄漏

沒有人知道關於內存通過*r3使用,比該內存由靜態成員函數Rectangle::operator new()如果存在通過全球配置功能::operator new分配,或以其他方式等。全球版本的內存通常被稱爲「免費商店」。

(所有三個對象r1r2*r3是所謂平等,因爲r2*r3構造爲r1副本。)

的情況,當你考慮成員變量會變得更加有趣:struct Foo { Rectangle r; };