C++ primer基礎(chǔ)之容器insert
C++ primer基礎(chǔ)之容器insert
今天學(xué)習(xí)C++ 基礎(chǔ)知識(shí)的時(shí)候遇到這樣問題,始終出現(xiàn)segments fault。最后才發(fā)現(xiàn)原來是自己對(duì)“容器insert之后迭代器會(huì)失效”的理解不夠透徹。
題目如下:
假定iv是一個(gè)int的vector,下面的程序存在什么錯(cuò)誤?你將如何修改?
auto iter = iv.begin();
auto mid = iv.begin() + iv.size() / 2;
while(iter != mid){
if(*iter == some_val)
iv.insert(iter, 2 * some_val);
}
我起初編寫的代碼如下:
/*************************************************************************
> File Name: 9.22.cpp
> Author: wanchouchou
> Mail: 200802376@qq.com
> Created Time: 2014年11月02日 星期日 16時(shí)34分20秒
************************************************************************/
#include<iostream>
#include<vector>
using namespace std;
int main(){
vector<int> vint = {1,1,1,1,1,3,4,1};
const int val = 1;
auto viBegin = vint.begin();
/*這里需要注意,如果vint.size小于等于1的話,viMid = viBegin 那么就不會(huì)進(jìn)入while循環(huán),所以我們應(yīng)當(dāng)單獨(dú)考慮這種情況*/
auto viMid = vint.begin() + vint.size()/2;
if(vint.empty()){
cout << "This vector is empty!" << endl;
return 0;
}
if(vint.size() == 1){
if(*viBegin == val){
vint.insert(viBegin, 2 * val);
}
goto print;
}
while(viBegin != viMid){
if(*viBegin == val){
vint.insert(viBegin, 2 * val);35 }
++viBegin;
}
print:
auto viEnd = vint.end();
viBegin = vint.begin();
while(viBegin != viEnd){
cout << *viBegin << ", ";
++viBegin;
}
cout << endl;
}
運(yùn)行的時(shí)候出現(xiàn) segmentation faulted.
從邏輯上來講,應(yīng)該是沒問題啊,那為什么又會(huì)出錯(cuò)呢?原來我忘記了對(duì)容器進(jìn)行插入操作的重要影響“除了end之外,所有的迭代器都會(huì)失效?。?!”。當(dāng)完成第一次插入之后,此時(shí)的viBegin和viMid已經(jīng)失效了,那么之后對(duì)其的所有操作都是非法的。所以我們必須在每一次插入操作之后對(duì)兩個(gè)迭代器重新賦值。鑒于對(duì)viMid的賦值比較麻煩,所以采用另外的方式記錄當(dāng)前迭代器是否到達(dá)容器的中點(diǎn),代碼如下:
/*************************************************************************
> File Name: 9.22.cpp
> Author: wanchouchou
> Mail: 200802376@qq.com
> Created Time: 2014年11月02日 星期日 16時(shí)34分20秒
************************************************************************/
#include<iostream>
#include<vector>
using namespace std;
int main(){
vector<int> vint = {1,1,1,1,3,4,1};
const int val = 1;
auto viBegin = vint.begin();
/*這里需要注意,如果vint.size小于等于1的話,viMid = viBegin 那么就不會(huì)進(jìn)入while循環(huán),所以我們應(yīng)當(dāng)單獨(dú)考慮這種情況*/
auto mid = vint.size() / 2;
if(vint.empty()){
cout << "This vector is empty!" << endl;
return 0;
}
if(vint.size() == 1){
if(*viBegin == val){
vint.insert(viBegin, 2 * val);
}
goto print;
}
while(distance(viBegin, vint.end()) > mid){
if(*viBegin == val){
viBegin = vint.insert(viBegin, 2 * val);
++viBegin;
}
++viBegin;
}
print:
auto viEnd = vint.end();
viBegin = vint.begin();
while(viBegin != viEnd){
cout << *viBegin << ", ";
++viBegin;
}
cout << endl;
}
運(yùn)行效果如下:
wanchouchou@wanchouchou-virtual-machine:~/c++/9.*$ ./9.22 2, 1, 2, 1, 2, 1, 2, 1, 3, 4, 1,
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
詳解C語言中scanf函數(shù)使用的一些注意點(diǎn)
這篇文章主要介紹了C語言中scanf函數(shù)使用的一些注意點(diǎn),scanf函數(shù)的使用是C語言入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2016-04-04
C/C++ Socket設(shè)置接收超時(shí)時(shí)間的多種方法
網(wǎng)絡(luò)編程中經(jīng)常需要處理的一個(gè)問題就是如何正確地處理Socket超時(shí),對(duì)于C/C++,有幾種常用的技術(shù)可以用來設(shè)置Socket接收超時(shí)時(shí)間,在這篇文章中,我們將詳細(xì)介紹如何在C/C++中設(shè)置Socket的非阻塞模式以及如何配置接收超時(shí)時(shí)間,需要的朋友可以參考下2024-01-01
VC++ 字符串String MD5計(jì)算小工具 VS2008工程
基于字符串加密的MD5算法,VS2008 VC++,多字節(jié)編譯工程。主要代碼如下,實(shí)現(xiàn)了ANSI字符串加密與Unicode字符串加密,需要的朋友可以參考下2017-07-07
基于C語言實(shí)現(xiàn)點(diǎn)餐系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了基于C語言實(shí)現(xiàn)點(diǎn)餐系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11

