2013-03-30 31 views
0

在下面的四種方法中,只有更好的是我們應該做的。我們希望在這裏動態分配以避免不良的函數返回。但是,我們在哪裏刪除f?刪除函數調用better()?但在這種情況下沒有更多。內存運行時錯誤:我們在哪裏刪除這個指針

Foo *bad() { 
    Foo f; 
    return &f; 
} 

Foo &alsoBad() { 
    Foo f; 
    return f; 
} 

Foo mediocre() { 
    Foo f; 
    return f; 
} 

Foo * better() { 
    Foo *f = new Foo; 
    return f; 
} 
+1

把它放入一個智能指針並返回,以使「更好」的工作更好。 – chris

+4

「平庸」實際上是最好的,只是說。參見[_Modern C++ Style_](http://klmr.me/slides/modern-cpp/#1)。另請參閱Bjarne Stroustrup討論移動語義的[_C++ 11 Style_](http://channel9.msdn.com/Events/GoingNative/GoingNative-2012/Keynote-Bjarne-Stroustrup-Cpp11-Style)。 – 2013-03-30 00:44:38

+1

你基本上在問:「我如何做記憶管理」,這是一個令人難以置信的廣泛而主觀的話題。 – Antimony

回答

5

But there is no f any more in that case.

好了,指針f超出範圍,這是事實,但我們的指針仍返回同一對象f指向。

因此,我們仍然有該對象的句柄,我們仍然可以在返回的指針上調用delete。實際上,在創建一個包含new的對象後,您可以在任何時候調用delete

你要照顧那是什麼:

  • 你確實在某些時候與new(否則你有內存泄漏)分配的每個對象調用delete;
  • 您不會爲同一個對象多次調用delete,否則會得到未定義的行爲;
  • 您不要取消引用指向已銷燬對象的指針(即「懸掛指針」),否則您會得到未定義的行爲。

通常,手工存儲器管理通過newdelete不鼓勵在現代C++,和所有權政策應通過智能指針代替來實現。 OR ...

In the four method below, only better is what we should do

不完全。實際上,我會說我們絕對不應該這樣做better() - 雖然我們可能做一個版本better()修改爲創建和返回一個智能指針,而不是一個擁有原始指針。

然而,功能mediocre()其實是相當不錯的,這是出於兩個原因:

  1. 首先,因爲它很可能編譯器會的Elid調用拷貝構造函數和執行(Named) Return Value optimization,從而導致沒有運行時間開銷;
  2. 其次,正是因爲有了C++ 11的移動語義,有可能 裝備Foo轉移構造使得由值 效率在大多數情況下,即使不進行省音返回。

此外,由於Zoidberg正確地在評論中提到,如果你不真的需要它們,你就不應該使用指針。通過創建具有自動存儲持續時間的對象(又名「在堆棧中」)可以實現獨特的所有權,並且移動語義使得這種做法高效。應該只創建指針when you need reference semantics

+1

我會加上最後一句話,在很多情況下,所有權可以在沒有任何指針(或參考,就此而言)的情況下表達。 – 2013-03-30 00:48:28

+0

@Zoidberg:絕對。會提到這一點。謝謝 –

+0

*確實在某些時候調用了'delete'以分配給所有使用'new'的對象*我承認這有時不像您想象的那樣容易,特別是如果您有不同的內存分配器時。所以'better'函數會有一個補充,'betterCallMeWhenYouAreDone'釋放分配的對象,你必須調用它而不是'delete'。 –