У меня есть класс, который имеет unordered_set<int>
элемент следующим образом:Weird поведения итератора + выдадут ошибку сегментации с unordered_set
У меня есть следующее определение класса с последующим его регулярными & конструкторами копирования, а также некоторые другие функции, изменяющий набор (удалены ненужные сегменты кода, так как класс очень долго):
#include <iostream>
#include <unordered_set>
#include <random>
class HexBoard {
public:
HexBoard(int n);
HexBoard(const HexBoard &obj);
std::unordered_set<int> emptyPositions();
private:
std::unordered_set<int> empty_positions;
};
HexBoard::HexBoard(int n) {
for (int i = 0; i < n * n; i++) {
empty_positions.insert(i);
}
}
HexBoard::HexBoard(const HexBoard &obj) : empty_positions(obj.empty_positions) {};
void HexBoard::placeStone(int i) {
checkBounds(i); // raises an error if i >= n
empty_positions.erase(i);
}
std::unordered_set<int> HexBoard::emptyPositions() {
return empty_positions;
}
у меня есть другой класс, который содержит экземпляр этого HexBoard. Она имеет функцию, которая будет копировать эту плату в другой переменной с помощью конструктора копирования:
class Game {
public:
Game(HexBoard::HexBoard *board) : board(board) {};
private:
HexBoard *board;
void monteCarlo(int position);
};
void Game::monteCarlo(int position) {
HexBoard *another_board = new HexBoard(*board);
int count = 0;
while (count < 5) {
count++;
std::uniform_int_distribution<unsigned> dis(
0, another_board->emptyPositions().size() - 1
);
std::cout << "Empty positons:\n";
for (const auto& pos : another_board->emptyPositions()) {
std::cout << pos << " ";
}
std::cout << "\n";
int n = dis(gen);
std::cout << "Picked random n: " << n << "\n";
auto it = another_board->emptyPositions().begin();
std::cout << "it begin: " << *it << "\n";
std::advance(it, n);
std::cout << "it advance: " << *it << "\n";
int absolute_position = *it;
std::cout << "picked " << absolute_position << "\n";
}
}
В функции monteCarlo
, скажем содержимое emptyPositions
набора были первоначально 8, 7, 6, 5, 4, 3, 2, 1
, выходной стандартный вывод этой функции, как правило:
Empty positons:
8 7 6 5 4 3 2 1
Picked random n: 4
it begin: 2
Segmentation fault: 11
Почему этот segfault? Я понимаю, что есть немного итератора тонко относительно линии empty_positions.erase(i);
, но даже когда я прокомментирую это, я получаю такое же поведение.
Я также добавил это право после Picked random n
стандартного вывода, и это, а также ошибок сегментации (выход ниже нее):
std::cout << "set buckets contain:\n";
for (unsigned i = 0; i < ai_board->emptyPositions().bucket_count(); ++i) {
std::cout << "bucket #" << i << " contains:";
for (auto j = ai_board->emptyPositions().begin(i);
j != ai_board->emptyPositions().end(i); ++j)
std::cout << " " << *j;
std::cout << std::endl;
}
Выход:
set buckets contain:
Segmentation fault: 11
происходит в выдаст ошибку сегментация std::advance(it, n);
и при этом последняя ручная итерация.
Буду признателен за любую помощь.
Благодаря
ли вы расположены аварии с отладчиком? Где это происходит? У вас есть нулевой указатель или другой указатель, выглядящий неинициализированным или, возможно, указателем на объект вне области видимости? –
Это происходит на 'std :: advance (it, n);' и на последнем сегменте, который у меня есть, где я пытался выполнить ручную итерацию. Ничего не выходит из сферы, нет указателей, если вы перечитаете это. Просто итераторы, контролируемые итераторами C++. – darksky