STL在很久以前就在使用了,当时记得是做一个基于OPENCV图像处理库,主要由C++编写的小游戏,STL用于处理游戏中的角色的死亡和添加、遍历,在那款游戏的设计中,STL并没有涉及到很细致的部分,但在最近进行一个需要大批量地使用STL的时候出现了很多的错误,重新细致地翻阅了c++Primer 之后,现在将错误进行总结并说明为何出错和如何改正。
vector ints;
for(int i = 0; i < 100; i++){
ints.push_back(i);
}
for (auto it = ints.cbegin(); it != ints.cend(); it++){
if ((*it) % 2 == 0){
ints.erase(it);
}
}
运行这个函数会让程序崩溃,具体原因是因为在erase成功之后,会让当前容器指向的所有迭代器失效,这时我们需要的是将此迭代器进行刷新,令其重新生效。
it = ints.erase(it);
容器的erase()操作不仅会删除容器中此迭代器指向的数据,还会返回指向此容器下一个数据的迭代器。
for (auto it = ints.cbegin(); it != ints.cend();){
if ((*it) % 2 == 0){
it = ints.erase(it);
}
else{
it++;
}
}
for (auto it = ints.cbegin(); it != ints.cend();){
for (int i = 0; i < 100; i++){
ints.push_back(i);
}
}
原因在于容器的存储原理是容器会在当前存储数据数量的基础上预留一定的内存来存储将要放下的数据,如果现在数据数量超过预留内存,容器将会在内存中重新开辟一块更大的内存,然后将自身复制到新内存中,并销毁现在所在的内存数据。这会导致容器的begin()和end()失效,当然迭代器也会失效。
vector ints;
ints.reserve(1000); for (auto it = ints.cbegin(); it != ints.cend();){
if (ints.size() == ints.capacity()){
break;
}
}
if (ints.size() == ints.capacity()){
break;
}
上面的代码大家应该能够看懂,不多说,可以根据具体情况进行自由发挥。今天先写到这些。