請教自定函式中傳回 new 的物件是否需 delete 的問題? |
答題得分者是:yyu10
|
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
依據各類與 C++ 有關的說明文件來看,凡是使用 new 指令來動態配置記憶體或產生的物件,都應該在使用完畢後將其 delete 掉,例如:
Graphics::TBitmap *Bitmap = new Graphics::TBitmap(); ... 處理過程 .... delete Bitmap; Bitmap = NULL;那麼在自定函數中若要動態產生一些物件來做暫存處理,並將處理結果傳回時,例如: Graphics::TBitmap* __fastcall TForm1::GetImage(void) { Graphics::TBitmap *tmpBitmap = new Graphics::TBitmap(); ... 處理過程 .... return tmpBitmap; }在這個例子中 new 了一個 tmpBitmap,並要在處理過後將其傳回,因此並未在函數中將其 delete 掉,程式執行時並未發生問題,但是讓我產生了如下的疑惑,請先進們指導一下: 1. 如果上述自定函數的做法沒有問題,那麼為何在 new 之後卻又不用 delete 掉呢? 2. 如果上述作法不妥,那麼該如何處理才是正確的作法? |
yyu10
中階會員 發表:9 回覆:99 積分:96 註冊:2005-02-18 發送簡訊給我 |
RedSnow, 你好 上述自定函數的做法沒有問題.
引言: 依據各類與 C 有關的說明文件來看,凡是使用 new 指令來動態配置記憶體或產生的物件,都應該在使用完畢後將其 delete 掉这段话是对整个程式而言的, 不一定要在同一个自定函數用delete. 当你使用完處理結果以后, 要记住用delete把動態記憶體释放掉. 比如 Graphics::TBitmap *Bitmap; Bitmap = GetImage(); ... 使用Bitmap .... delete Bitmap; Bitmap = NULL;發表人 - yyu10 於 2005/03/20 16:51:19 |
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
yyu10 您好: 您所舉的例子:
Graphics::TBitmap *Bitmap; Bitmap = GetImage(); ... 使用Bitmap .... delete Bitmap; Bitmap = NULL;這我是知道的,我所困惑的是例子中 GetImage 函數所 new 出來的那個 tmpBitmap,如果在 GetImage 函數中未將其 delete 掉的話,是否會有記憶體未被釋放的現象?還是說系統會在執行程序離開該函數之後,自動的將它清除掉? 發表人 - RedSnow 於 2005/03/21 00:19:13 |
yyu10
中階會員 發表:9 回覆:99 積分:96 註冊:2005-02-18 發送簡訊給我 |
系統不会自動清除 new 出來的記憶體. new 出來的記憶體会一直存在, 直到程式將其 delete 掉. 在 GetImage 函數中没有用 delete, 所以系統不會在離開該函數时自動的將它清除掉, 記憶體确实未被釋放. 但这并不是错误, 只要记着在程式其它地方將其 delete 掉就行了.
引言:另外, GetImage 将得到的記憶體傳回, 表明程式其它地方还将用到这块記憶體, 因此不应该在 GetImage 中將其 delete 掉. 發表人 - yyu10 於 2005/03/21 09:02:01Graphics::TBitmap* __fastcall TForm1::GetImage(void) { Graphics::TBitmap *tmpBitmap = new Graphics::TBitmap(); ... 處理過程 .... return tmpBitmap; } |
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
yyu10 您好: 我依據您的說明將我的問題整理成如下的例舉與解釋,請再幫我看看是否正確?
Graphics::TBitmap* __fastcall TForm1::GetImage(void) { Graphics::TBitmap *tmpBitmap = new Graphics::TBitmap(); ... 處理過程 .... return tmpBitmap; } void __fastcall TForm1::SomeProc(void) { Graphics::TBitmap *Bitmap = new Graphics::TBitmap(); Bitmap = GetImage(); ... 其它處理過程 .... delete Bitmap; Bitmap = NULL; }1. 在 SomeProc 程序中 new 出來的 Bitmap 配置了一塊記憶體空間 A。 2. Bitmap 呼叫 GetImage 時,GetImage 函數中 new 出來的 tmpBitmap 亦配置了一塊記憶體空間 B。 3. 在 GetImage 程序結束時,將 tmpBitmap 所配置空間 B 的位址指標傳回。 4. 在 SomeProc 程序中 Bitmap 配置的空間位址重新指向 GetImage 函數所傳回的位址 B (原配置的記憶體 A 自動釋放掉?)。 5. 如果 Bitmap 呼叫了其它類似會傳回 TBitmap 指標的函數,則 Bitmap 配置的空間亦再度重新指向 (原配置的記憶體 B 自動釋放掉?)。 如果上述解釋是正確的,那麼現在就只剩下第 4 與第 5 項括號內的描述我還未能確認了,總之;在我的觀念裡,似乎範例中總有一處的記憶體是由系統 "自動釋放" 掉,或者是做了 "重新配置" 的動作,否則難以解釋 new 與 delete 未能匹配的狀況。 |
yyu10
中階會員 發表:9 回覆:99 積分:96 註冊:2005-02-18 發送簡訊給我 |
RedSnow, 您好, 简单的说, 您的例舉存在memory leak(記憶體未被釋放的現象). 您的解釋1, 2, 3是正确的.
引言: 4. 在 SomeProc 程序中 Bitmap 配置的空間位址重新指向 GetImage 函數所傳回的位址 B (原配置的記憶體 A 自動釋放掉?)。原配置的記憶體 A 没有釋放掉, 因为系统不会自動释放new出來的記憶體. 这需要写程式的人自己用delete来释放. 换句话说, 每一个new都应该有一个与之匹配的delete, 这样才不会引起memory leak. new和delete可以在同一函數中使用, 也可以分开. 你可以在函數A中用new得到一块記憶體, 然后在函數B中用delete将这块記憶體釋放掉. 您的例程需要改动一下, Graphics::TBitmap* __fastcall TForm1::GetImage(void) { Graphics::TBitmap *tmpBitmap = new Graphics::TBitmap(); ... 處理過程 .... return tmpBitmap; } void __fastcall TForm1::SomeProc(void) { Graphics::TBitmap *Bitmap = new Graphics::TBitmap(); ... 用到Bitmap(記憶體空間A)的處理過程 .... delete Bitmap; // delete 和上面的new匹配 Bitmap = GetImage(); ... 用到Bitmap(記憶體空間B)的處理過程 .... delete Bitmap; // delete 和GetImage中的new匹配 Bitmap = NULL; }發表人 - yyu10 於 2005/03/21 18:55:30 |
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
|
雲中鵝
一般會員 發表:14 回覆:24 積分:7 註冊:2004-12-21 發送簡訊給我 |
#include
------
Try it! |
雲中鵝
一般會員 發表:14 回覆:24 積分:7 註冊:2004-12-21 發送簡訊給我 |
|
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |