从std::vector中移除时出现分割故障
Segmentation fault when removing from std::vector
我试图删除结构向量中的重复,这种重复是由结构中的qieid
确定的:
struct infotable
{
int qieid;
int fid;
int valid;
};
我写了一个子函数来做这个:
void erase_duplicate(vector<infotable> &info)
{
vector<infotable>::iterator it0,it1;
for(it0 = info.begin();it0 != info.end()-1; it0++)
{
//it1 = find(qieidarray1.begin(),it0,*it0);
for(it1 = it0 +1;it1 != info.end(); it1++)
{
if((*it1).qieid == (*it0).qieid)
it1 = info.erase(it1);
}
}
}
但是这段代码我有一些问题。当vector中struct的数量很少时,它工作得很好。但是当我在vector中有超过3000个结构体时,程序就会出错,我有:
分段故障11
显示在我的屏幕上。我知道这是一个内存访问问题,我可能会访问到我不应该接触的地方,因为向量中有很多元素。但无论如何,我可以改善我的代码,以获得更好的性能(运行更多的元素)?
您也可以使用<algorithm>
函数来做,特别是std::unique
。
首先,按qieid
排序,然后使用unique
,它将"已删除"的元素移动到末尾并返回一个新的迭代器,然后您可以使用它实际擦除这些元素。
std::sort(info.begin(), info.end(), [](const infotable& a, const infotable& b) {
return a.qieid < b.qieid;
});
auto newIt = std::unique(info.begin(), info.end(), [](const infotable& a, const infotable& b) {
return a.qieid == b.qieid;
});
info.erase(newIt, info.end());
这将在O(n+log n)内运行,而您的原始解决方案具有O(n2)时间复杂度。就我个人而言,我更喜欢这个解决方案,特别是因为它更具表现力,所以更容易看到代码在做什么。
注意:如果你的编译器已经支持c++ 14的泛型lambdas,你可以使用[](const auto& a, const auto& b) { ... }
当你使用erase时,它会使迭代器失效。
for(it1 = it0 +1;it1 != info.end(); )
{
if((*it1).qieid == (*it0).qieid)
it1 = info.erase(it1);
else
it1++;
}
您可以使用std::set
技巧删除副本,它可读性强,易于维护,但效率较低。
std::vector<int> r = {14,26,58,56,26,14};
std::set<int> s(r.begin(),r.end());
r = std::vector<int>(s.begin(),s.end());
您需要给std::set您自己的比较函数,以便它与您的结构一起工作。
相关文章:
- 分割故障C++矩阵
- C ,二进制树的高度,而不是检查我的子树是否为空,而是在检查我的子树是否是叶子节点.抛出分割故障
- 我正在为此代码分割故障
- 在执行strcpy时获取分割故障错误
- 空隙指针分割故障
- Xcode会产生分割故障,而不是例外
- OPENCV C 中的分割故障误差
- 分割故障:核心倾倒C 矢量对字符串:
- C 2D数组导致分割故障(核心倾倒)
- 分割故障/错误读数变量-C 列表
- DLSYM导致分割故障
- 使用C 中的操作员删除的分割故障
- 使用Linux X64下的Libmozjs-52(SpidermonKey)进行分割故障
- 使用长变量时分割故障(11)错误
- C - 返回字符串时的分割故障
- 创建VertexArray时的分割故障
- 向量分割故障的向量
- 从std :: fileSystem ::路径对象的类中退出时的分割故障
- C 矢量分割故障
- 基于向量的数据格式的分割故障误差