为什么在调用erase和push_back函数后,下列元素同时出现在这个c++ vector的头和尾?
Why does the following element appear at both the head and tail of this c++ vector after a call to erase and push_back?
我试图理解为什么以下代码的行为方式:
std::vector<int*> k;
for (int i = 0; i < 5; ++i) k.push_back(new int(i));
for (int i = 0; i < k.size(); ++i)
std::cout << "k[" << i << "]: " << *k[i] << "@" << k[i] << ", ";
std::cout << std::endl;
for (int i = 0; i < k.size(); ++i) {
int* p = k[i];
delete p;
if (i >= 2) {
k.erase(k.begin(), k.begin() + i);
k.push_back(new int(5));
break;
}
}
for (int i = 0; i < k.size(); ++i)
std::cout << "k[" << i << "]: " << *k[i] << "@" << k[i] << ", ";
std::cout << std::endl;
当我运行这个,我们第一次打印k
的内容,我看到这样:
[0]: 0@0x1774e010, k[1] 1@0x1774e050, k[2]: 2@0x1774e030, k[3]: 3@0x1774e070, k[4]: 4@0x1774e0c0
这正是我所期望的。然后在擦除和push之后,我希望前两个元素消失,最后三个元素被移动,第5个元素出现在最后。然而,我得到的却是这个:
k[0]: 5@0x1774e030, k[1]: 3@0x1774e070, k[2]: 4@0x1774e0c0, k[5]: 5@0x1774e030,
我确实看到k[5]
出现在其他元素移动后的末尾,但我不理解为什么它也出现在第一个元素。
vector::erase
的第二个参数是end迭代器后的。这是标准c++库中迭代器范围的典型形式。
所以,当i == 2
语句k.erase(k.begin(), k.begin() + i)
只擦除前两个元素,留下你刚刚删除的一个仍然在向量中。当您尝试使用已删除的指针时,这会导致错误的结果。
(从技术上讲,执行erase
也是未定义的行为,因为它涉及读取已删除的指针)。
可能,你看到k[0]: 5@0x1774e030
而不是随机垃圾的原因是你的new int
重新分配到与delete
相同的空间;我猜那行k[5]:
是k[3]:
的错别字
相关文章:
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 在c++中用vector填充一个简单的动态数组
- vector.resize()中的分配错误
- 使用std::vector的OpenCL矩阵乘法
- POCO::PostgreSQL:如何将std::vector支持添加到`Binder::bind`
- 在某些循环内使用vector.push_back时出现分段错误
- 当vector是tje全局变量时,c++中vector的内存管理
- std::vector的包装器,使数组的结构看起来像结构的数组
- 为什么(-1)%vector::size()总是返回0
- 在C++中将类(带有Vector成员)保存为二进制文件
- 编译器如何区分std::vector的构造函数
- 将 int 数组转换为 std::vector<int*>
- 使用 pqxx 将 std::vector 存储在 postgresql 中,并从数据库中检索它
- 在std::vector上存储带有模板的类实例
- 在main()之外初始化std::vector会导致性能下降(多线程)
- 为什么std::vector比数组慢
- std::vector::迭代器是否可以合法地作为指针
- 如何将二进制格式的 C++ 对象的 std::vector 保存到磁盘?
- 循环中的条件:为什么每次都调用strlen(),而vector.size()只调用一次
- 为什么std::vector和std::valarray初始化构造函数不同