<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
主要作用就是讓演演算法能夠不用關心底層資料結構,其底層實際就是一個指標,或者是對指標進行了封裝。比如:vector的迭代器就是原生態指標T*。因此迭代器失效,實際就是迭代器底層對應指標所指向的空間被銷燬了,而使用一塊已經被釋放的空間,造成的後果是程式崩潰(即如果繼續使用已經失效的迭代器,程式可能會崩潰)。
凡是涉及到擴容操作,都有可能引起迭代器失效,因為vector擴容是分配一個新的陣列,然後全部元素移到新的陣列中。
下面我們就以Insert函數來舉例說明!
範例1:
void test02() { // 在所有的偶數的前面插入2 vector<int> v; v.push_back(1); v.push_back(2); v.push_back(3); v.push_back(4); v.push_back(5); v.push_back(6); cout << v.size() << ":" << v.capacity() << endl; vector<int>::iterator it = v.begin(); while (it != v.end()) { if (*it % 2 == 0) { v.insert(it, 20); ++it; //這裡++是為了解決第二種迭代器失效,防止原地踏步 } ++it; } cout << v.size() << ":" << v.capacity() << endl; for (auto e : v) { cout << e << " "; } cout << endl; }
程式崩潰!
程式碼解釋:如果我們沒有預先分配空間,那麼在insert的時候會發生擴容,根據我們模擬實現vector可知,STL標準庫的vector中insert函數是實現了對迭代器的更新,但是形參列表沒有使用輸出型引數,所以我們只有通過返回值來接收新的迭代器!
範例2:
如果我們用返回值來接受新的迭代器,則不會崩潰!
void test02() { // 在所有的偶數的前面插入2 vector<int> v; v.push_back(1); v.push_back(2); v.push_back(3); v.push_back(4); v.push_back(5); v.push_back(6); cout << v.size() << ":" << v.capacity() << endl; vector<int>::iterator it = v.begin(); while (it != v.end()) { if (*it % 2 == 0) { it = v.insert(it, 20);//stl中的insert如果發生了擴容是實現了對it位置的更新,並用返回值輸出了形參的改變 ++it; //這裡++是為了解決第二種迭代器失效,防止原地踏步 } ++it; } cout << v.size() << ":" << v.capacity() << endl; for (auto e : v) { cout << e << " "; } cout << endl; }
6:6
9:9
1 20 2 3 20 4 5 20 6
請按任意鍵繼續. . .
程式碼解釋:
STL中的insert如果發生了擴容是實現了對it位置的更新,並用返回值輸出了形參的改變。
範例3:
如果我們預先預留(reserve)了空間,再插入過程中沒發生擴容,那麼自然也不會失效了。
void test02() { // 在所有的偶數的前面插入2 vector<int> v; v.reserve(20); v.push_back(1); v.push_back(2); v.push_back(3); v.push_back(4); v.push_back(5); v.push_back(6); cout << v.size() << ":" << v.capacity() << endl; vector<int>::iterator it = v.begin(); while (it != v.end()) { if (*it % 2 == 0) { //it = v.insert(it, 20); v.insert(it, 20); ++it; ++it; } cout << v.size() << ":" << v.capacity() << endl; for (auto e : v) { cout << e << " "; } cout << endl; }
一般vector刪除資料,都不考慮縮容的方案。縮容方案: size() < capacity()/2時,可以考慮開一個size()大小的空間,拷貝資料,釋放舊空間。縮容方案本質是時間換空間。一般設計都不會考慮縮容,因為實際比較關注時間效率,不關注空間效率,因為現在硬體裝置空間都比較大,空間儲存也比較便宜。
範例4:
void test03(){ vector<int> v; cout << v.size() << ":" << v.capacity() << endl; v.reserve(10); v.push_back(1); v.push_back(2); v.push_back(3); v.push_back(4); cout << v.size() << ":" << v.capacity() << endl; auto pos = find(v.begin(), v.end(), 2); if (pos != v.end()) { v.erase(pos); } cout << v.size() << ":" << v.capacity() << endl; for (auto e : v) { cout << e << " "; } cout << endl; cout << *pos << endl; //只要一存取 系統強制檢查(怎麼檢查的不知道!), 就報錯(Linux沒報錯) *pos = 10; cout << *pos << endl << endl; }
程式碼解釋:可見程式碼確實是實現了刪除,但是程式卻崩了,原因就是erase後pos失效了,pos的意義變了,(但是在不同平臺下對於存取pos的反應是不一樣的,因此我們使用的時候要特別小心,統一以失效的角度去看待)。但如果不存取pos指向的內容就不會崩潰!
erase導致的失效:
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45