实战c++中的vector系列--emplace_back造成的引用失效
C++ -- 系列 实战 引用 失效 vector 造成
2023-09-11 14:20:45 时间
上篇将了对于struct或是class为何emplace_back要优越于push_back,可是另一些细节没有提及。今天就谈一谈emplace_back造成的引用失效。
直接撸代码了:
#include <vector>
#include <string>
#include <iostream>
using namespace std;
int main()
{
vector<int> ivec;
ivec.emplace_back(1);
ivec.emplace_back(ivec.back());
for (auto it = ivec.begin(); it != ivec.end(); ++it)
cout << *it << " ";
return 0;
}
//输出:
1 -572662307
尝试1:不直接给emplace_back传递ivec.back():
#include <vector>
#include <string>
#include <iostream>
using namespace std;
int main()
{
vector<int> ivec;
ivec.emplace_back(1);
auto &it = ivec.back();
ivec.emplace_back(it);
for (auto it = ivec.begin(); it != ivec.end(); ++it)
cout << *it << " ";
return 0;
}
输出:
1 -572662307
尝试2:不给emplace_back传递引用:
#include <vector>
#include <string>
#include <iostream>
using namespace std;
int main()
{
vector<int> ivec;
ivec.emplace_back(1);
auto it = ivec.back();
ivec.emplace_back(it);
for (auto it = ivec.begin(); it != ivec.end(); ++it)
cout << *it << " ";
return 0;
}
输出:
1 1
我们如愿以偿,这时候应该能够得到结论了,ivec.back()返回的是引用,可是这个引用失效了,所以才会输出不对;我们之前也提到过,又一次分配内存会造成迭代器的失效,这里是造成了引用的失效。
再回头看看emplace_back的描写叙述:
if a reallocation happens, all iterators, pointers and references related to this container are invalidated.
Otherwise, only the end iterator is invalidated, and all other iterators, pointers and references to elements are guaranteed to keep referring to the same elements they were referring to before the call.
进一步。
尝试3:避免emplace_back引起又一次分配内存:
#include <vector>
#include <string>
#include <iostream>
using namespace std;
int main()
{
vector<int> ivec;
ivec.reserve(4);
ivec.emplace_back(1);
ivec.emplace_back(ivec.back());
for (auto it = ivec.begin(); it != ivec.end(); ++it)
cout << *it << " ";
return 0;
}
输出:
1 1
可是这个时候问题来了,假设不使用emplace_back而改用push_back呢?
#include <vector>
#include <string>
#include <iostream>
using namespace std;
int main()
{
vector<int> ivec;
ivec.push_back(1);
ivec.push_back(ivec.back());
ivec.push_back(ivec.back());
ivec.push_back(ivec.back());
for (auto it = ivec.begin(); it != ivec.end(); ++it)
cout << *it << " ";
return 0;
}
//输出:
1 1 1 1
为什么使用push_back就不失效呢?
相关文章
- 【C/C++学院】0723-32位与64位/调戏窗口程序/数据分离算法/内存检索/二分查找法/myVC
- Linux全栈工程师--传智播客C++公开课之全栈工程师修成记
- 【C/C++学院】(29)网络编程--实现跨平台传输文件(TCP版)
- 【C/C++学院】(21)Mysql数据库编程--开发简介/SQL语句
- C++矩阵处理库--Eigen初步使用
- C/C++中的const--常量指针与指针常量
- C/C++每日一练(20230324)
- Open3D(C++) Ransac拟合平面分割点云
- VC++技术内幕(第四版)笔记--SetWindowExt和SetViewportExt
- paip.c++程序崩溃的汇编级别调试-打印堆栈-gcc gdb
- C++数据结构--泛型编程
- C++设计模式:策略模式
- 【C++】使用局部变量赋值而非引用,导致内存多次释放的野指针问题
- 解答私信@被c++折磨头秃的花季美少女 //C++ 利用指针数组输入10个单词,编写函数对10个单词进行排序并输出,要求判断是否有相同的单词,如果有相同的单词在输出时该单词只输出一次。
- 解答私信@被c++折磨头秃的花季美少女 //C++ 编写一个进阶版的进制转换程序,运行功能如下:请选择要输入的数字的进制(2、8、10、16):请输入该数字:请选择要转换成的进制(2、8。。。
- VS 更改C++模式
- C++ std::function的用法
- C++学习--台阶问题
- C++ Primer 学习笔记_41_STL实践与分析(15)--先来看看算法【下一个】
- Ubuntu20.04下,qt交叉编译报错::15: warning: identifier ‘nullptr‘ is a keyword in C++11 [-Wc++0x-compat]
- C++ Primer 学习笔记_95_用于大型程序的工具 --多重继承与虚继承
- C++ Primer 学习笔记_91_用于大型程序的工具 --命名空间
- 学习设计模式--观察者模式(C++)
- C++中priority_queue 使用
- C语言个人感悟以及与C++之间的区别之经典
- C++编程经验(2):为虚基类做虚析构函数的必要性
- C++学习笔记4--表达式