c++ - 可以乱序插入向量吗?
问题描述
我想vec1
通过vec2
and插入vec3
。当我vec3
先插入时,程序无法成功退出。但是当我 insertvec2
然后 insertvec3
时,程序可以成功退出。我想知道失败的原因。
为什么插入vec1
乱序:我想通过两个不同的线程插入(两个线程会写入不同的位置,互不影响),所以不能保证顺序。
#include <iostream>
#include <vector>
#include <chrono>
using namespace std::chrono;
using namespace std;
struct DocIdAndPayLoad
{
uint64_t m_docId;
DocIdAndPayLoad()
{
DefaultCnt++;
}
DocIdAndPayLoad(const DocIdAndPayLoad& /*_bond_rhs*/)
{
CopyCnt++;
}
DocIdAndPayLoad(DocIdAndPayLoad&& _bond_rhs)
{
MoveCnt++;
}
DocIdAndPayLoad& operator=(const DocIdAndPayLoad& _bond_rhs)
{
AssignCnt++;
return *this;
}
static int DefaultCnt;
static int CopyCnt;
static int MoveCnt;
static int AssignCnt;
};
int DocIdAndPayLoad::DefaultCnt = 0;
int DocIdAndPayLoad::CopyCnt = 0;
int DocIdAndPayLoad::MoveCnt = 0;
int DocIdAndPayLoad::AssignCnt = 0;
int main()
{
const int hugeSize=10000;
vector<DocIdAndPayLoad> vec1;
cout<<vec1.size()<<" "<<vec1.capacity()<<endl;
vector<DocIdAndPayLoad> vec2(hugeSize/2);
vector<DocIdAndPayLoad> vec3(hugeSize/2);
auto start1 = high_resolution_clock::now();
vec1.reserve(hugeSize);
//vec1.insert(vec1.begin()+hugeSize/2, std::make_move_iterator(vec3.begin()), std::make_move_iterator(vec3.end()));
vec1.insert(vec1.begin(), std::make_move_iterator(vec2.begin()), std::make_move_iterator(vec2.end()));
auto stop1 = high_resolution_clock::now();
auto duration = duration_cast<microseconds>(stop1 - start1);
cout << "Cost1: "<< duration.count() << " microseconds" << endl;
vector<DocIdAndPayLoad> vec4;
auto start2 = high_resolution_clock::now();
vec4.resize(hugeSize);
auto stop2 = high_resolution_clock::now();
auto duration2 = duration_cast<microseconds>(stop2 - start2);
cout << "Cost2: "<< duration2.count() << " microseconds" << endl;
cout<<vec1.size()<<" "<<vec1.capacity()<<endl;
return 0;
}
解决方案
该reserve
调用设置向量的容量,但不设置其大小。这意味着调用后向量仍然为空
vec1.reserve(hugeSize);
该向量中的任何索引都将超出范围并导致未定义的行为。
更重要的是,由于向量为空,vec1.begin()
会返回结束迭代器(即vec1.begin() == vec1.end()
),所以vec1.begin()+hugeSize/2
无效!.
尝试取消引用end
迭代器(或超出)会导致未定义的行为和可能的崩溃。
推荐阅读
- jsf - 如何使用 h:commandLink 更新和打开 ap:dialog 而无需重新加载其他组件
- javascript - 如何将 react-i18next 与语义 UI 标签标签结合使用?
- laravel - Laravel orm with() 不起作用
- android - 如何修复 zsh:在 MacOS 上的 Android Studio 终端上运行 Gradle 命令时权限被拒绝
- php - 如何将文本区域的内容与php数组中的值进行比较?
- java - 如何在不导入任何包的情况下在 Java 中使用 Calendar 类?
- javascript - 使用 selenium 向下滚动 Div
- ruby-on-rails - Rails 关联不保存到数据库
- javascript - Safari 中的 IntersectionObserver API 不稳定
- php - 我可以通过 URL 参数值过滤自定义帖子类型项目吗?