[問題] 關於new delete

看板C_and_CPP作者 (夜夜米)時間15年前 (2010/07/19 00:06), 編輯推噓0(0017)
留言17則, 5人參與, 最新討論串1/1
( *[1m *[m 為色碼,可以按 Ctrl+V 預覽會顯示的顏色 ) ( 未必需要依照此格式,文章條理清楚即可 ) 遇到的問題: (題意請描述清楚) delete物件時在執行時產生error! 簡單的說 我定義兩個物件 大的物件裡面有一個小的物件: class SMALL{ int *data; //動態陣列指標 int n; //動態陣列大小 SMALL(int i){ data=new int[i]; n=1; //contructor: new陣列 } ~SMALL(){ clear();} //destructor: 呼叫clear()清除陣列資料 clear(){ delete[] data;} //delete陣列 SMALL operator=(SMALL x){ data=new int[x.n]; n=x.n; } }; class BIG{ SMALL s; //有一個SMALL物件 BIG(){ s=SMALL(1);} //contructor: 初始化SMALL物件 ~BIG(){ s.clear();} //destructoc: 清除SMALL資料 }; 簡而言之 我有一個物件SMALL 裡面有new一個動態陣列 SMALL物件裡面有一個clear()函式可以delete陣列 另一個物件BIG裡有個SMALL物件 BIG的destructor裡會呼叫SMALL的clear(); 感覺上沒什麼問題 但是當我主程式這麼寫: int main(){ BIG* x; x=new BIG; delete x; return 0; } compile和build沒問題 進入執行時就當掉了..... === Debug Assertuon Failed! Program D:\....... File: dbgheap.c Line:1044 Expression: _CrtIsValidHeapPointer(pUserData) ...... === 然而 當我把BIG destructor裡面的s.clear()砍掉之後 程式就順利執行而且不會當掉了 但是 這樣子我的SMALL裡面的動態陣列的記憶體會被歸還回OS嗎? 另外 為什麼原先的寫法不行呢? 看他的描述似乎是記憶體堆疊有問題 但是是哪什麼問題啊? 我實在搞不懂 謝謝各位解大 希望得到的正確結果: 正確結束程式且正確歸還記憶體給OS 程式跑出來的錯誤結果: 執行時走到delete物件時當掉 === Debug Assertuon Failed! Program D:\....... File: dbgheap.c Line:1044 Expression: _CrtIsValidHeapPointer(pUserData) ...... === 開發平台: (例: VC++ or gcc/g++ or Dev-C++, Windows or Linux) VC 6.0 有問題的code: (請善用置底文標色功能) 已經寫在上面了 補充說明: -- 劍是凶器,劍術是殺人之術 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 111.248.14.241 ※ 編輯: yayarice 來自: 111.248.14.241 (07/19 00:07) ※ 編輯: yayarice 來自: 111.248.14.241 (07/19 00:08)

07/19 00:10, , 1F
SMALL的解購子在BIG解購的時候會被呼叫
07/19 00:10, 1F

07/19 00:13, , 2F
soga! 那原本那樣子為什麼會有問題呢?
07/19 00:13, 2F

07/19 00:14, , 3F
原本是因為不確定所以才這樣寫的 但是沒想到會有這種問題
07/19 00:14, 3F

07/19 00:18, , 4F
s.clear()呼叫完s.data指向未用memory區塊 BIG destructor
07/19 00:18, 4F

07/19 00:19, , 5F
又呼叫一次s的destructor delete s.data...
07/19 00:19, 5F

07/19 00:19, , 6F
另外 SMALL的operator=這樣寫會有memory leakage
07/19 00:19, 6F

07/19 00:26, , 7F
噢噢 我再自己程式裡operator=有先delete再new...
07/19 00:26, 7F

07/19 00:26, , 8F
不過我不太能理解的是"s.data指向未用memory區塊"
07/19 00:26, 8F

07/19 00:27, , 9F
我以為他是指向NULL delete了之後不會指向NULL嗎?
07/19 00:27, 9F

07/19 00:28, , 10F
簡單說你對一個位址 delete 兩次
07/19 00:28, 10F

07/19 00:29, , 11F
要 NULL 要自己設定
07/19 00:29, 11F

07/19 00:29, , 12F
恩 的確是delete了兩次 因為我以為delete的物件若指向NUL
07/19 00:29, 12F

07/19 00:29, , 13F
的話delete就會自動跳出 所以看來delete了之後並不指向
07/19 00:29, 13F

07/19 00:30, , 14F
NULL囉?
07/19 00:30, 14F

07/19 00:31, , 15F
嗯 operator=記得還要檢查是不是自己 不然delete掉就糗囉
07/19 00:31, 15F

07/19 00:31, , 16F
delete之後不會自動改指NULL 這個動作要自己來
07/19 00:31, 16F

07/19 00:31, , 17F
原來如此 謝謝各位解惑!!
07/19 00:31, 17F
文章代碼(AID): #1CGoPmXT (C_and_CPP)