C++中带有List类的迭代器Segfault

Iterator Segfault with List class in C++

本文关键字:迭代器 Segfault List C++      更新时间:2023-10-16

我正在为我的一个comp-sci类做一个项目,该类使用哈希表将字符串从STL的列表类排序为链表向量。在列表中插入字符串时,除索引3之外的所有索引都会导致SEGFAULT错误。我不知道为什么会发生这种事。以下是插入函数的代码,以及我收到的几个错误示例。向量"表"被声明为在默认构造函数中包含4个元素

void Stringset::insert(string word)
{
cout << "insertion" << endl;
hash<string> stringHash;
int hashIndex = stringHash(word) % size;
cout << hashIndex << endl;
bool exists = false;
//find intended index and create base boolean variable for whether or not the value already exists
list<string>::iterator pos = table[hashIndex].begin();
list<string>::iterator end = table[hashIndex].end();
for(pos; pos != end; pos++){
cout << "pass" << endl;
if((*pos).compare(word) == 0){
exists = true;
}
}
if(!exists){
table[hashIndex].push_back(word);
num_elems++;
cout << "inserted " << (*pos) << endl;
}
else{
}
}

以下是SEGFAULT的几个例子,以及插入3工作的情况:

I: insert word
F: find word
R: remove word
P: print words in stringset
Q: quit
I
Enter word to insert: By
insertion
3
inserted 
I: insert word
F: find word
R: remove word
P: print words in stringset
Q: quit
I
Enter word to insert: Try
insertion
3
pass
inserted 
I: insert word
F: find word
R: remove word
P: print words in stringset
Q: quit
I
Enter word to insert: Error
insertion
2
Segmentation fault (core dumped)

连同一个特例:

I: insert word
F: find word
R: remove word
P: print words in stringset
Q: quit
I
Enter word to insert: Error
insertion
2
Segmentation fault (core dumped)

h以及Stringset对象的默认构造函数:

#pragma once
#include <string>
#include <vector>
#include <list>
using namespace std;
//Stringset class, do not modify definitions for existing members
class Stringset
{
private:
vector<list<string>> table;
int num_elems;
int size;
public:
Stringset();
vector<list<string>> getTable() const;
int getNumElems() const;
int getSize() const;
void insert(string word);
bool find(string word) const;
void remove(string word);
};
Stringset::Stringset() : table(4), num_elems(0), size(4) {}

我很确定,一旦程序进入for循环,它总是会崩溃,但由于我不熟悉迭代器,我不确定为什么。任何关于如何解决这个问题的想法都将不胜感激。

我会仔细检查hashIndex计算。它可能会导致SEGFAULT。此外,您可以使用一些c++语法来避免一些头疼的问题。看看下面的变化:

//list<string>::iterator pos = table[hashIndex].begin();
//list<string>::iterator end = table[hashIndex].end();
bool exists = false;
for (auto& Pos : table[hashIndex]) {
cout << "pass" << endl;
if (Pos.compare(word) == 0) {
exists = true;
break;
}
}
if (!exists) {
table[hashIndex].push_back(word);
num_elems++;
//cout << "inserted " << (*pos) << endl;   
//Pos was pointing to the .end() in your coude
cout << "inserted " << table[hashIndex].back() << endl;
}

您的代码基本上是正确的。

错误在您的cout << "insert" ...行中。正如在注释中已经指出的,当您到达代码行时,(*pos)指向endl,它"超出"了列表。这意味着它不再指向有效的对象。这会导致segfault。

如果我评论掉那句话,它对我有用。

ps-我在上面的评论中的怀疑是错误的。你的构造函数是正确的:-(