Re: [問題] vector<T>中erase()與dtor呼叫時機的關係
※ 引述《masan22305 (海豹)》之銘言:
: 開發平台(Platform): (Ex: VC++, GCC, Linux, ...)
: Windows codeblock12.11 GCC 4.7.1
: 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...)
: no
: 程式碼(Code):(請善用置底文網頁, 記得排版)
: Q1: http://ideone.com/qhnWs8
: Q2: http://ideone.com/szu4Jh
首先這兩支程式有兩個共同的問題:
1) new char[...] 的時候要多留一格用來存 '\0'
所以 A(const char* str) 裡要用 new char[strlen(str) + 1]
Q1 裡的 A(const A& a) 裡要用 new char[strlen(str) + 2]
2) 實作 copy constructor 的時候, 同時要實作 destructor
和 operator=
事實上如果你有實做 operator= 同時印出訊息的話應該看得出發生什麼事
: -------------------------------------------------------------
: 問題1:
: 為什麼vector中呼叫destructor的順序
: 跟一般物件呼叫destructor的順序不同?
: 物件不是會保持"後進先出"的原則嗎?
不是: vector 只是可變動大小陣列, 保証 destruct 時會 destruct 所有內容
要從 [0] 跑到 [n-1] 還是反過來沒有規定.
: 問題2:
: 為什麼Avec.erase(iter)呼叫到的destructor竟然是
: ~A() called and cptr is 3?
: iter現在指到的物件不是應該是a1嗎?
: 接下去的destructor順序雖然a1似乎是不見了
: 但是a3的內容似乎也被delete掉了
因為 erase(iter) 時 iter 指到的是 [0]
vector 的記憶體管理比較僵硬 (跟 deque 相比), 一定要用 [0] .. [n-1]
不能用 [1] .. [n]
所以現在有 data[0].ptr = "1"; data[1].ptr = "2"; data[2].ptr = "3"
erase([0]) 的時候 vector 必需
data[0] = data[1];
data[1] = data[2];
data[2].~A();
於是就看到 "3" 被 destruct 了
然後再看看 destruct 這個 vector 時發生了什麼事?
data[0].~A(); => cptr = "2"
data[1].~A(); => cptr ~~~> "3" ?
但是剛剛 data[2].~A(); 的時候就已經把這個 cptr destruct 掉了
所以就 undefined behavior 了
---
總結: 實作 copy constructor 時, 一定要同時實作 destructor 和 operator=
: --------------------------------------------------------------
: 以上兩個新手問題還請各位大大幫忙!!
--
A man may die, countries may rise and fall, but an idea lives on.
- John F. Kennedy
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 128.36.232.45
→
06/06 19:10, , 1F
06/06 19:10, 1F
→
06/06 19:12, , 2F
06/06 19:12, 2F
推
06/06 19:17, , 3F
06/06 19:17, 3F
推
06/06 22:34, , 4F
06/06 22:34, 4F
→
06/06 22:36, , 5F
06/06 22:36, 5F
推
06/08 00:09, , 6F
06/08 00:09, 6F
推
06/08 02:46, , 7F
06/08 02:46, 7F
→
06/08 02:47, , 8F
06/08 02:47, 8F
→
06/08 02:58, , 9F
06/08 02:58, 9F
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 2 之 2 篇):
C_and_CPP 近期熱門文章
PTT數位生活區 即時熱門文章