Vector 其实就类似动态数组. 事先分配好一定量的内存. 当需要的内存值大于某个阀值. 就重新申请内存. 重新分配. 当小于某个阀值, 也会导致重新分配.(自动收缩部分, stl没有明确规定, 有些库实现了)
正确: code1
vector<string> vecFiles;
vector<string>::iterator it_pos;
//@todo 已下载文件过滤
for (it_pos = vecFiles.begin(); it_pos != vecFiles.end(); ) {
string strTmp = *it_pos;
if( objDownHis.checkHisList( strTmp.c_str() ) ){ //判断是否已下载过, 已下载则从列表删除
g_Log << TIME << "file:[" << *it_pos << "] found "<< END; //
vecFiles.erase(it_pos++);
}else
it_pos++;
}
正确: code2
vector<string> vecFiles;
vector<string>::iterator it_pos;
//@todo 已下载文件过滤
for (it_pos = vecFiles.begin(); it_pos != vecFiles.end(); ) {
string strTmp = *it_pos;
if( objDownHis.checkHisList( strTmp.c_str() ) ){ //判断是否已下载过, 已下载则从列表删除
g_Log << TIME << "file:[" << *it_pos << "] found "<< END; //
it_pos = vecFiles.erase(it_pos);
}else
it_pos++;
}
错误: code3
vector<string> vecFiles;
vector<string>::iterator it_pos;
//@todo 已下载文件过滤
for (it_pos = vecFiles.begin(); it_pos != vecFiles.end(); it_pos++) {
string strTmp = *it_pos;
if( objDownHis.checkHisList( strTmp.c_str() ) ){ //判断是否已下载过, 已下载则从列表删除
g_Log << TIME << "file:[" << *it_pos << "] found "<< END; //
vecFiles.erase(it_pos);
}
}
code3 错误的原因为, vecFiles.erase(it_pos); 当前的it_pos已经被删除了, 再下一次循环的时候 it_pos++, 访问非法内存..
然后回过头来看code1, vecFiles.erase(it_pos++); 在当前的it_pos已经被删除的时候, it_pos已经指向下一个位置了. 虽然这里逻辑上是错误的. 但是利用c语法的特性产生了一个正确的结果, 算是一个技巧. 不算是一门技术.
code2, it_pos = vecFiles.erase(it_pos); erase删除的时候, 也返回了下一个指针的位置,我们将这个位置保留了, 所以这种做法也是正确的.
另外一个移植性比较好的做法是remove_if 和一个仿函数.
仿函数可以是:
struct check {
check( Object * objDownHis ) : m_obj( objDownHis ) {}
check( const check & c ) : m_obj( c.m_obj ) {}
bool operator()(const string & s) const {
if ( m_obj->checkHisList( s.c_str() ) {
g_Log .........
return true;
}
return false;
}
Object * m_obj;
};
vecFiles.erase( std::remove_if( vecFile.begin(), vecFile.end(), check( &objDownHis ) );
鸣谢p大, lancey, jackz 排名不分先后.. 全按交流时间顺序...