c++ - 在某些循环内使用 vector.push_back 时出现分段错误
问题描述
根据教授的要求,我目前正在 Cygwin 终端上使用 g++。
我应该接受一个输入文件并逐字阅读,然后将所有单词放在一个向量中,按字母顺序排序并且没有重复。
但是,每次我尝试在某些循环内操作我的向量(即 push_back)时,我的程序都会出现分段错误。
这是我的代码片段:
void word_count(ifstream& input){
string temp;
vector<string> v;
input >> temp; //set first variable
v.push_back(temp);
while (!input.eof()) { //I'm aware of the limitations while using !eof, this is just the way I am required to loop over a file
input >> temp;
for (vector<string>::iterator i = v.begin(); i != v.end(); i++) { //check entire vector for word
if (*i == temp) { //just break and skip the word if it already exists
break;
}
if (i == v.end() - 1) { //if the word doesn't exist yet
for (vector<string>::iterator k = v.begin(); k != v.end(); k++) { //re-search the vector for the proper place
if (k == v.end() - 1) { //if at the end, just push_back the vector
v.push_back(temp); //Causes segmentation fault
break;
}
if ((*k < temp) && (*(k + 1) > temp)) { //find correct place and insert the word in the vector
v.insert(k, temp); //Also causes segmentation fault if execution even manages to get this far
}
}
}
}
}
}
第 5 行的第一个 push_back 非常好,我可以多次复制和粘贴而不会出错。我也可以在输入>> temp(在while循环内部)之后立即push_back而不会出错。但是,如果我在“k”循环下尝试 push_back,则会出现分段错误。我完全被难住了。
我试过在 StackOverflow 上查看其他与向量相关的问题,但我真的不明白为什么我可以(或不能)在某些地方使用 push_back。
提前感谢您的帮助!
编辑1:我应该提到我在VS 2019中对其进行了测试。弹出向量库文件,说明抛出了“读取访问违规”异常。没有分段错误(或者这可能是 VS 告诉我发生分段错误的方式?)
编辑 2:修改向量会使迭代器无效。不知道,谢谢大家的帮助!
编辑 3:我只允许使用向量,而不是集合或其他容器。如果我可以使用一套,我完全会。
解决方案
当您修改向量迭代器时,它变得无效。
有两个原因:
- 当您
push_back
和std::vector::capacity被破坏时,分配新块数据并将数据移动/复制到新缓冲区 - 当您在中间添加/删除项目时,旧迭代器可以指向可能不再存在的不同项目。
有快速修复它的方法。当您进行修改时,您必须获取迭代器的更新值。poush_back
没有这样的功能,但std::vector::insert将迭代器返回到新值,并且此迭代器可用于更新 for 循环迭代器。
我可以修复你的代码,但它非常复杂(缩进很多),我希望避免这种情况。您应该首先将此代码切片为更小的函数。
而是挽救您的代码,这是我的版本:
template<typename Iter>
size_t count_unique_items(Iter begin, Iter end)
{
using value_type = typename std::iterator_traits<Iter >::value_type;
std::unordered_set<value_type> unique_items;
std::copy(begin, end, std::inserter(unique_items, unique_items.end()));
return unique_itmes.size();
}
size_t count_unique_words(std::istream& input)
{
return count_unique_items(std::istream_iterator<std::string>{input}, {});
}
推荐阅读
- codeigniter - 在我的 codeigniter 视图页面上显示来自同一数据库表但具有不同类别的数据(使用相同的模型和控制器)
- version-control - 如何在 Visual SourceSafe 的历史视图中查看注释?
- flutter - 如何使用 Flutter 测试 GridView 小部件的所有元素是否导航到新屏幕?
- django - 带有假主机头的 Django 服务器端请求伪造
- oracle - 如何对运行数据导入(impdp)的oracle docker容器进行健康检查
- json - 使用 Swift 加载异步 json - 加载时间长的问题
- css - 如何从 Vue 组件中获取 CSS 值?
- php - Codeigniter Ajax:电子商务查询已经在工作,但显示数据是问题
- arduino - Wemos 调制解调器睡眠并每 5 分钟发送一次数据
- mysql - sql子字符串建议