文本旨在对 C++ 的容器 vector 进行肤浅的分析。
#include
#include
using namespace std;
int main() {
std::vector<int> v = {8, 5, 6, 2, 4, 7};
for (auto i = v.begin(); i != v.end();) {
cout << i.base() << " " << v.begin().base() << endl;
if (*i == 2) {
i = v.erase(i);
} else {
i++;
}
}
cout << "size : " << v.size() << endl;
for (auto j = v.begin(); j != v.end(); j++) {
cout << (*j) << endl;
}
}
先说明一下 vector.erase() 就是动态数组的指定位置的删除,其返回值为指向下一个元素( 或 end() ) 的迭代器。 而关于迭代器需要知道的点为
这也就是下面 vector v 的首地址为72b0,每次进行 i++ ,其基地址就加了 4 ,一个 int 的字节量。而在删除了 元素 2 之后,迭代器的值仍然为 72bc,但是在删除之后这个值志向了元素 4。完美的解释了代码。那么问题的出现请看第二节。

#include
#include
using namespace std;
int main() {
std::vector<int> v = {8, 5, 6, 2, 4, 7};
for (auto i = v.begin(); i != v.end();) {
// cout << i.base() << " " << v.begin().base() << endl;
if (*i == 8) {
v.push_back(88);
i = v.erase(i);
} else {
i++;
}
}
cout << "size : " << v.size() << endl;
for (auto j = v.begin(); j != v.end(); j++) {
cout << (*j) << endl;
}
此时在添加了一个新的元素后,再进行删除操作会发生段错误。而且为什么会有两个88。这就是我遇见的问题所在。虽然用 int + vector 和 打印地址的方式可以很快地发现问题。但我面对的是 vector
而且一般来说,也没人会打印迭代器的基地址。虽然打印了问题就能一目了然了,但我是煞笔 此时为什么会有两个88,而且元素 5 去哪了。这就是问题的所在了。但是答案其实就在 vector 的定义和名称中,动态数组 。最后答案的揭晓在第三节。 
#include
#include
using namespace std;
int main() {
std::vector<int> v = {8, 5, 6, 2, 4, 7};
for (auto i = v.begin(); i != v.end();) {
cout << i.base() << " " << v.begin().base() << endl;
if (*i == 8) {
v.push_back(88);
i++;
} else {
i++;
}
}
cout << "size : " << v.size() << endl;
for (auto j = v.begin(); j != v.end(); j++) {
cout << (*j) << endl;
}

最开始 v 的首地址为b2b0,但是在添加了一个元素之后其首地址发送了改变,aka 内存发现了一片新的区域来更合适的存储这个数组,从而动态地发生了改变。但是此时我们设定的迭代器并未改变。可以看出在进行了 275 次自加操作后,迭代器才完成了对于新数组的访问。

结尾处 的来两个88也很好解释了,在最开始的 元素8 处,向数组中添加了一个 88。从而导致了数组 v的内存地址发生了改变。在经历了漫长的自加操作后,迭代器 i 又找到了一个元素 8,就又添加了一个新的元素 88。
至此问题结束,数组动态地删除指定元素的模板就是第一节的代码,不要在删除的过程中添加新的元素,反之亦然!!!。希望可以帮到你,wish u all the best.