Итератор Segfault с классом List в C ++ - PullRequest
0 голосов
/ 26 февраля 2020

Я работаю над проектом для одного из моих классов Comp Sci, который использует таблицы Ha sh для сортировки строк в вектор связанных списков из класса списков 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)

Stringset.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) {}

Я вполне уверен, что он всегда один раз падает программа запускается для l oop, но я не уверен, почему из-за моего незнакомства с итераторами. Будем весьма благодарны за любые идеи относительно того, как это исправить.

Ответы [ 2 ]

0 голосов
/ 26 февраля 2020

Ваш код в основном правильный.

Ошибка в вашей строке cout << "insert" .... Как уже указывалось в комментариях (*pos) указывает на endl, когда вы добираетесь до той строки кода, которая находится «за пределами» списка. Это означает, что он больше не указывает на действительный объект. Это приводит к segfault.

Если я закомментирую эту строку, это работает для меня.

ps - мое подозрение в моем комментарии выше было неверным. Ваш конструктор правильный: -)

0 голосов
/ 26 февраля 2020

Я бы дважды проверил расчет 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...