2014-04-07 56 views
0

我的第一個問題是函數中的new分配的內存在函數結束時會自動刪除(釋放)。新的內存分配

int* foo() 
{ 
    int *a = new int; //memory allocated for an int 
    *a = 3; 
    return (a); 
}//function ends -- is memory for integer still allocated. 

如果存儲器自動函數結束後取消分配,那麼不應該我的下一個代碼給與訪問不屬於我的記憶有些誤差。

int main() 
{ 
    int *x = foo(); 
    cout<<*x; 
} 
+0

'了'從未佔用內存的整數。它佔用一個指向整數的指針的內存。當函數結束時,你想知道該內存是否仍然分配/有效。指針('a')發生什麼並不相關。 – leemes

+0

@leemes我編輯了我的問題。現在是否正確? – hoder

+1

是的。我不想糾正你的措辭,而是想確保你正確地理解它。 – leemes

回答

7

不,它當然不會。每new必須與delete平衡。 (並且,爲了避免任何疑問,任何new[]必須與delete[]平衡)。

C++中有一些構造函數,一旦容器對象超出範圍,將允許有效釋放內存。看看std::shared_ptrstd::unique_ptr

+0

爲什麼從'std :: shared_ptr'開始,甚至沒有提到更簡單,輕量級的'std :: unique_ptr'? – Angew

+0

@Angew:感謝您的建議:我已將'unique_ptr'添加到答案中。 – Bathsheba

2

不,內存未被釋放。

你應該delete a;

手動釋放它在如Java或C#有一個處理內存釋放,當它發現,一些數據沒有不再需要所謂的垃圾收集器的語言。垃圾收集可以用於C++,但它不是標準的,實際上很少使用。

但是,您可以使用其他機制來自動釋放內存。共享指針就是其中之一。他們引入額外的開銷。在常規的C++代碼中,程序員通常負責手動管理內存(分配和解除分配)。對於初學者來說,在切換到更高級的機制之前學習基礎是很重要的。

+0

爲什麼他應該自動進行手動操作? –

+0

這是一個風格問題。使用'shared_ptr'等開銷太大了。 – Bathsheba

+0

恕我直言,編輯(介紹最後一段)會破壞這個好的答案。 – Bathsheba

0

不,這是你的責任,促使釋放:

int *i = new int; 
delete i; 

然而,上面的代碼遲早會演變成的東西,幾乎是不可能做出異常安全。最好不要使用指針可言,或者如果你真的必須使用智能指針,將在適當的時候釋放內存,爲您提供:

std::shared_ptr<int> i (new int); 
*i = 0xbeef; 
return i; 

存在着多種所有制的語義其他智能指針。對於大多數現實世界的應用程序來說,由智能指針引入的任何強加的或假定的開銷通常會比較昂貴(我真的指節省金錢)的東西,比如可維護性,可擴展性,異常安全性(其中所有混合到其他兩個)。

不要忘記存在替代指針,根據不同的情況:

  • 標準集裝箱:如果你需要的東西像陣列
  • 智能指針:如果您真的需要一個指針
  • 參考文獻:你不能忘記取消分配
  • 普通對象:根本沒有指針。依靠複製和移動,這通常會使高度的可維護性,可擴展性,異常安全性以及的性能。 在C++中,這應該是您的默認選擇。
0

這是從功能內動態分配並取決於某些其他功能釋放的憐憫的不良做法。理想情況下,調用者應該分配空間,將其傳遞給調用函數,調用者可以在不使用時釋放空間。

void foo(int * a) 
{ 
    // a is pre-allocated by caller 
    *a = 3; 
}//function ends -- caller takes care of allocation and deallocation 

int main() 
{ 
    int *x = new int; // memory allocated for an int by caller 
    foo(x); // pass x as argument 
    cout << *x; 
    delete x; // deallocate, not required any more 
    return 0; 
} 
+0

這不一定是壞習慣,一切取決於你想做什麼。 –

0

如上所述,沒有原始指針永遠不會被自動刪除。這就是爲什麼我們不使用原始指針來控制生命週期的原因。我們使用智能指針。

下面是現代C++編寫正確的代碼片段:

std::unique_ptr<int> foo() 
{ 

    return std::unique_ptr<int>(new int(3)); 
    // or std::make_unique<int>(3) for c++14 

    // function will either std::move the unique_ptr or emplace it efficiently 
} 

int main() 
{ 
    // x will either be created in-place or move-constructed by foo() 
    std::unique_ptr<int> x = foo(); 

    // potential bug! pointers can be null 
    if (x) { 
    std::cout << *x; 
    } 
    else { 
    std::cout << "x is null\n"; 
    } 
} 
+0

另一個:)(純運氣,沒有跟蹤你:D) –