[英]C++, will this cause memory leak?
我知道我無法獲得本地變量的引用。 如:
int& func1()
{
int i;
i = 1;
return i;
}
而且我知道這是正確的,但是在調用func2()之后必須刪除它
int* func2()
{
int* p;
p = new int;
*p = 1;
return p;
}
int main()
{
int *p = func2();
cout << *p << endl;
delete p;
return 0;
}
如果函數是這樣的:
MyClass MyFunction()
{
return new MyClass;
}
MyClass的整個定義是:
class MyClass
{
public:
MyClass() : num(1){}
MyClass(MyClass*) : num(10){}
int num;
};
這會導致內存泄漏嗎?
我應該如何避免呢? 該函數返回的對象不是指針,那么如何刪除它呢?
PS:該代碼來自《 R ++上的書》第10章。原始代碼為:
Picture frame(const Pictrue& pic)
{
// Picture has a constructor Picture(*P_Node)
// Frame_Pic derives from P_Node
// So the constructor Picture(*P_Node) will implicitly convert Frame_Pic to Picture.
return new Frame_Pic(pic);
}
MyClass MyFunction()
{
return new MyClass;
}
這實際上是錯誤的。您正在返回一個指針。 所以應該
MyClass* MyFunction()
如果您的功能與我上面提到的一樣,並且在使用后不刪除它,則會泄漏內存。
我應該如何避免呢? 該函數返回的對象不是指針,那么如何刪除它呢?
那是編譯錯誤。因此刪除它的意義不會增加
使用具有指針構造函數的更新后的MyClass
,我想您應該編寫:
MyClass MyFunction() {
MyClass *ptr = new MyClass;
MyClass retval(ptr);
delete ptr; // the dynamically-allocated object isn't needed any more
return retval;
}
碰巧是異常安全的,因為MyClass的構造函數不能拋出,但是作為一般規則,在不將結果直接放入智能指針的情況下,您實際上絕對不應該調用new
:
MyClass MyFunction() {
std::unique_ptr<MyClass>(new MyClass);
return MyClass(ptr);
}
無論如何,這是一個相當荒謬的情況-如果您要按價值返回,則完全沒有理由調用new
:
MyClass MyFunction() {
MyClass tmpvalue;
return &tmpvalue; // doesn't actually return the pointer, just an object
// constructed from it
}
而且由於指針的值甚至沒有被指針構造函數使用,因此您也可以這樣寫:
MyClass MyFunction() {
return 0; // returns an object constructed from a null pointer
}
在您引用本書的原始代碼中,我猜想Picture
類具有一個P_Node*
類型的數據成員,該成員在其中存儲指針值,並在其析構函數中對該指針調用delete
。 希望作者也對Picture
的復制構造函數和復制賦值運算符進行一些操作,以防止復制后出現雙重釋放。 我沒有這本書,所以無法檢查我的猜測,但是Picture
的代碼應該顯示它是如何完成的。
[編輯:哦,那是Koenig和Moo的書之一。 他們勝任(勝任),所以可以肯定他們的Picture
類正確地處理了資源。 如果不是,那是因為這是故意做錯事的例子。]
一個簡單的檢查是這樣的:
N
個new
數,則必須在程序中使用N
個兼容的 1 delete
,以避免內存泄漏2 。 那你是在做嗎 是的,在第一種情況下(您正在做new int
),您確實做到了。 沒有內存泄漏。
剩下的帖子對我來說還不夠清楚!
1.通過兼容 delete
,我的意思是,如果您以ptr = new T[M]
的形式使用new
,那么兼容delete
應采用delete []ptr
的形式。 同樣, delete ptr
與ptr = new T
兼容。
2.當然,如果您使用一些智能指針,則不必顯式使用delete
。
它與您的“ func2”示例相同。 曾經稱為“框架”的人最終需要釋放返回的圖片。
MyClass MyFunction()
{
return new MyClass;
}
是錯誤的,因為operator new返回指向MyClass的指針,但是您的函數返回MyClass,而不是MyClass *
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.