作者yayarice (夜夜米)
看板C_and_CPP
標題[問題] 關於new delete
時間Mon Jul 19 00:06:01 2010
( *[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)
→ freesamael:SMALL的解購子在BIG解購的時候會被呼叫 07/19 00:10
→ yayarice:soga! 那原本那樣子為什麼會有問題呢? 07/19 00:13
→ yayarice:原本是因為不確定所以才這樣寫的 但是沒想到會有這種問題 07/19 00:14
→ hilorrk:s.clear()呼叫完s.data指向未用memory區塊 BIG destructor 07/19 00:18
→ hilorrk:又呼叫一次s的destructor delete s.data... 07/19 00:19
→ hilorrk:另外 SMALL的operator=這樣寫會有memory leakage 07/19 00:19
→ yayarice:噢噢 我再自己程式裡operator=有先delete再new... 07/19 00:26
→ yayarice:不過我不太能理解的是"s.data指向未用memory區塊" 07/19 00:26
→ yayarice:我以為他是指向NULL delete了之後不會指向NULL嗎? 07/19 00:27
→ akasan:簡單說你對一個位址 delete 兩次 07/19 00:28
→ akasan:要 NULL 要自己設定 07/19 00:29
→ yayarice:恩 的確是delete了兩次 因為我以為delete的物件若指向NUL 07/19 00:29
→ yayarice:的話delete就會自動跳出 所以看來delete了之後並不指向 07/19 00:29
→ yayarice:NULL囉? 07/19 00:30
→ hilorrk:嗯 operator=記得還要檢查是不是自己 不然delete掉就糗囉 07/19 00:31
→ james732:delete之後不會自動改指NULL 這個動作要自己來 07/19 00:31
→ yayarice:原來如此 謝謝各位解惑!! 07/19 00:31