EE_DSnP 板


LINE

剛剛用open office編輯結果它當了,害我要重打,要養成存檔的好習慣。 老師下課說在版上去年這時候應該有文章,不過我找了好久都找不到阿, 後來翻閱一下手邊的工具書,覺的應該是POD造成的問題(Plain Old Data)。 寫個小程式測試一下: #include <iostream> #include <vector> using namespace std; class POD { int i; }; class NonPOD { double i; ~NonPOD() { } }; template<class T> void test() { typedef T* Pointer; Pointer p = new T[10]; void *v = reinterpret_cast<void*> (p); size_t* size = reinterpret_cast<size_t*> (v - sizeof(size_t)); cout << *size << endl; } int main() { test<POD> (); test<int> (); test<std::vector<int> > (); test<NonPOD> (); } 此程式在我的電腦編譯(g++4.4.3)執行結果為: 49 49 10 10 什麼是POD呢?簡單說就是class沒有定義constructor/copy constructor/assignment operator/destructor這四種,完全靠compiler generated版本(這個版本也稱作 trivial – constructor/....),那是POD跟這個array刪除有什麼關聯阿? 這可以從這次作業HW1.2.2這題看起,在Vector中,我們要初始化_data這個pointer, 我們會寫_data = new unsigned[size]; 如果你沒有用一個迴圈去初始化每個值,當直接 讀取 時,有時後會得到垃圾值。若我們想要讓他們都能夠初始化成unsigned的預設值呢? 可以寫: _data = new unsigned[size](); 我們再看到Matrix,在constructor內要初始化_data,不過這時候問題來了: _data = new Vector[numRows]; 會呼叫Vector的哪一個constructor阿? 如果你有用_data[1].size()去讀出它的值,會發現是0,也就是 Vector::Vector(unsigned = 0);被呼叫了。 我們可以看到,在初始化一個陣列時我們只能(implicitly or explicitly)呼叫其 default constructor,我們從int的例子可以發現,不加上()時,constructor不會被呼叫, 而不會把每個元素的初始值設為零;而在Vector的例子,編譯器有看到default constructor,因此判定它不是POD,implicitly呼叫每個元素的default ctor。 (當你把在Vector::Vector的預設參數拿掉時,編譯器就會唉啦:你沒給我一個 default constructor我怎麼建構阿?而且你已經寫了constructor了, 我更不可能幫你寫一個阿!!) 這就是編譯器對待不同類型的type會有不同的處理方式!! 如果你的class沒有寫任何constructor,編譯器就會幫你寫一份,但那份 裡面什麼都不做。 (對copy ctor跟assignment operator而言則是 memner wise assignment, 所以你呼叫Vector a(b);//利用另一個Vector b來建構a 是會通過編譯的,只不過在a,b被摧毀時delete 2 _data指的記憶體。 ) 好,重點來了,對於destructor而言,編譯器幫你寫得那份,有要作什麼用嗎? 答案是:沒有,而且對於內建型別(int double)而言也是一樣, 所以在上面的測試程式中,我們看到POD, int得到的是相似結果, 而std::vector<int>與NonPOD得到的是10的結果,也就是陣列大小。 編譯器知道陣列大小要作什麼用阿?答案就是在摧毀陣列時明白呼叫其destructor囉! for(int I = 0; I < size; ++i){ _data[I].~Vector(); } 而沒有定義destructor的POD,只要把記憶體刪除,這個物件也就掰了~~ 所以int[]與POD[]都不需要存陣列大小。 ※ 引述《puerpuella (柏亨)》之銘言: 我在寫作業的時候對delete產生了一點疑惑... 我本來以為delete是刪除一個object用的,而delete[]是刪除多個用的 但是我在main()中宣告 double* d = new double[1]; 之後不管我寫delete d; 或delete []d; 執行都會成功 而且就算我是宣告double* d = new double[0]; 時也可以 可是我寫了一個class叫做C,在main()中 C* c = new C[1]; delete c; 這樣執行就不過了,一定要用delete[]才OK 是因為宣告時如果有用[ ],delete的時候就要加嗎? 可是在double的時候好像不用加[]也行? --



※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.112.245.114
1F:推 ric2k1:new [] 的變數用 delete 只會 delete 其中的一個,其他的 10/11 22:20
2F:推 ric2k1:會變成 memory leak. 照理來說不會馬上 crash,如果會crash 10/11 22:20
3F:→ ric2k1:應該是其他原因 10/11 22:21
4F:推 ric2k1:簡單的說: 用 new [] 就要用 delete [], 反之用 new 則要用 10/11 22:22
5F:→ ric2k1:delete. 10/11 22:22
6F:→ ric2k1:明天上課會再說明一下。 10/11 22:23
7F:→ puerpuella:謝謝教授!!我後來又試了一下如果我C裡面沒寫destructor 10/11 22:34
8F:→ puerpuella:就不會有事,可是一加上~C()就掛了.. 10/11 22:34
9F:推 ric2k1:這個跟去年的 HW1.2 P3 有關... 我明天來一起講解一下! 10/11 23:04
10F:推 johnjohnlin:要作 deep copy 吧?我之前也這樣 10/12 15:50
簡單講應該也是deep copy啦XDDDDDDDDd 附註一下: Exceptional C++ (我是看國際中文版,英文版應該是3e?) Item 36:有寫到 一般的compiler在destructor通常的實做方式為, 會在dtor函式碼尾端有一個不可見旗標, 如果此變數是一個auto物件(非new出來的)則此旗標為false 若是一個dynamic物件,則此旗標為true 這個旗標代表的是『當這物件被摧毀時,我該刪除它嗎?』 如果為true,則在尾端呼叫正確(就是該class)的operator delete() (忘了說,class defined operator delete隱喻為static) 若class B有virtual dtor,且也有(static) B::operator delete(void*); class D為其derived class,但只定義(static) D::operator delete(void*); 則 D* ptr = new D; delete ptr;//喚起D::operator delete(void*) 但 B* ptr2 = new D; delete ptr2;//因為有virtual dtor,喚起~D(), ~D()內則一樣喚起D::operator delete(void*); 所以compiler其實有幫我們作一些事情的(在trivial內)。 ※ 編輯: tomap41017 來自: 140.112.244.171 (10/13 01:17)
11F:推 ric2k1:推一個!! 抱歉,我說的文章是 #2451 10/13 01:11
12F:→ tomap41017:突然覺的我寫得落落長 囧 10/13 01:19
13F:推 ric2k1:不會啊! 講得很清楚!! 感謝 10/13 01:41
14F:推 aitjcize:大推! 10/14 00:49







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:BuyTogether站內搜尋

TOP