Vector subscript out of range - c++

i have a little problem with my game. When i'm trying to check that the bullet and ennemy are colliding i'm randomly getting an error "Vector subscript out of range", im not sure that this is a problem, but i'm deleting my vector in two places:
//Checking if enemy is crossing a bullet
for (size_t i = 0; i < ennemies.size(); i++)
{
ennemies[i].update(player);
if (player.getGlobalBounds().intersects(ennemies[i].getGlobalBounds()))
{
player.kill();
}
for (size_t j = 0; j < bullets.size(); j++)
{
if (ennemies[i].getGlobalBounds().intersects(bullets[j].getGlobalBounds()))
{
ennemies.erase(ennemies.begin() + i);
bullets.erase(bullets.begin() + j);
ilosc--;
}
}
}
Here is the second place:
for (int i = 0; i < Level::LEVEL_HEIGHT; i++)
{
for (int j = 0; j < Level::LEVEL_WIDTH; j++)
{
if (level.tiles[i][j].tileType != 0)
{
if (x.intersects(map[i][j].getGlobalBounds()))
kolX = true;
else if (y.intersects(map[i][j].getGlobalBounds()))
kolY = true;
for (int k = 0; k < bullets.size(); k++)
{
if (bullets[k].getGlobalBounds().intersects(map[i][j].getGlobalBounds()))
{
bullets.erase(bullets.begin() + k);
ilosc--;
}
}
}
}
}
and here is the whole code of a main class:
#include "Engine.h"
Engine::Engine()
{
//wczytywanie bg
bgTexture.loadFromFile("data\\textures\\bg.png");
bgSprite.setTexture(bgTexture);
//wczytywanie textur
for (int i = 1; i < level.iloscTextur; i++)
{
tiles[i].loadFromFile("data\\textures\\tiles.png", IntRect((i-1)*level.TILE_WIDTH, 0, 32, 32));
}
//ustawianie kafli
for (int i = 0; i < Level::LEVEL_HEIGHT; i++)
{
for (int j = 0; j < Level::LEVEL_WIDTH; j++)
{
if (level.tiles[i][j].tileType != 0)
{
map[i][j].setPosition(j * Level::TILE_WIDTH, i * Level::TILE_HEIGHT);
map[i][j].setTexture(tiles[level.tiles[i][j].tileType]);
}
}
}
}
Engine::~Engine()
{
}
//Renderowany poziom gry
void Engine::runEngine(RenderWindow & window)
{
//Zegary do pętli stałokrokowej, pocisków i przeciwników
Time UpdateTime = Time::Zero;
Time czasOdPocisku = Time::Zero;
Time czasDoSpawnu = Time::Zero;
Clock przeciwnicy;
Clock zegar;
Clock czasPocisku;
const Time StepTime = seconds(1.f / 60.f);
const Time WaitTime = seconds(0.1);
Time EnemySpawn = enemy.losujSpawn();
bool menu = false;
while (!menu)
{
Time czas = zegar.restart();
UpdateTime += czas;
//Pętla aktualizujaca logikę gry
while (UpdateTime > StepTime)
{
czasOdPocisku = czasPocisku.getElapsedTime();
czasDoSpawnu = przeciwnicy.getElapsedTime();
UpdateTime -= StepTime;
Event event;
Vector2f mouse = window.mapPixelToCoords(Mouse::getPosition(window));
player.update(mouse);
if (window.pollEvent(event))
{
if (event.type == Event::Closed)
menu = true;
if ((Keyboard::isKeyPressed(Keyboard::Left) && WaitTime < czasOdPocisku) || (Keyboard::isKeyPressed(Keyboard::Right) && WaitTime < czasOdPocisku) ||
(Keyboard::isKeyPressed(Keyboard::Up) && WaitTime < czasOdPocisku) || (Keyboard::isKeyPressed(Keyboard::Down) && WaitTime < czasOdPocisku))
{
czasPocisku.restart();
bullets.push_back(bullet);
bullets[ilosc].addBullet(player);
ilosc++;
}
}
//Spawn przeciwników
if (EnemySpawn < czasDoSpawnu)
{
czasDoSpawnu = przeciwnicy.restart();
EnemySpawn = enemy.losujSpawn();
for (int i = 0; i < enemy.losujPrzeciwnikow(); i++)
ennemies.push_back(enemy);
}
//aktualizacje logiki
for (int i = 0; i < bullets.size(); i++)
{
bullets[i].update();
}
//Checking if enemy is crossing a bullet
for (size_t i = 0; i < ennemies.size(); i++)
{
ennemies[i].update(player);
if (player.getGlobalBounds().intersects(ennemies[i].getGlobalBounds()))
{
player.kill();
}
for (size_t j = 0; j < bullets.size(); j++)
{
if (ennemies[i].getGlobalBounds().intersects(bullets[j].getGlobalBounds()))
{
ennemies.erase(ennemies.begin() + i);
bullets.erase(bullets.begin() + j);
ilosc--;
}
}
}
czyKoliduje(player.ruch(StepTime));
}
window.clear();
window.draw(bgSprite);
//Rysowanie poziomu
for (int i = 0; i < Level::LEVEL_HEIGHT; i++)
{
for (int j = 0; j < Level::LEVEL_WIDTH; j++)
{
window.draw(map[i][j]);
}
}
//Rysowanie pociskow
for (int i = 0; i < bullets.size(); i++)
{
window.draw(bullets[i]);
}
for (int i = 0; i < ennemies.size(); i++)
{
window.draw(ennemies[i]);
}
window.draw(player);
window.display();
}
}
//Kolizje
void Engine::czyKoliduje(Vector2f ruch)
{
FloatRect x = player.getGlobalBounds();
FloatRect y = player.getGlobalBounds();
x.left += ruch.x;
y.top += ruch.y;
bool kolY = false, kolX = false;
for (int i = 0; i < Level::LEVEL_HEIGHT; i++)
{
for (int j = 0; j < Level::LEVEL_WIDTH; j++)
{
if (level.tiles[i][j].tileType != 0)
{
if (x.intersects(map[i][j].getGlobalBounds()))
kolX = true;
else if (y.intersects(map[i][j].getGlobalBounds()))
kolY = true;
for (int k = 0; k < bullets.size(); k++)
{
if (bullets[k].getGlobalBounds().intersects(map[i][j].getGlobalBounds()))
{
bullets.erase(bullets.begin() + k);
ilosc--;
}
}
}
}
}
if (!kolX)
player.move(Vector2f(ruch.x, 0));
if (!kolY)
player.move(Vector2f(0, ruch.y));
}

All of your loops that are calling erase() on containers are not taking into account that the size of the containers change when you erase items from them. To properly loop through a container while erasing items from it, you should use iterators instead of indexes. erase() returns a new iterator that points to the item after the erased item, so you can continue looping.
std::vector<enemy>::iterator i = ennemies.begin();
while (i != ennemies.end())
{
i->update(player);
if (player.getGlobalBounds().intersects(i->getGlobalBounds()))
{
player.kill();
}
bool hit = false;
for (std::vector<bullet>::iterator j = bullets.begin(); j != bullets.end); ++j)
{
if (i->getGlobalBounds().intersects(j->getGlobalBounds()))
{
hit = true;
i = ennemies.erase(i);
j = bullets.erase(j);
ilosc--;
break;
}
}
if (!hit)
++i;
}
for (int i = 0; i < Level::LEVEL_HEIGHT; i++)
{
for (int j = 0; j < Level::LEVEL_WIDTH; j++)
{
if (level.tiles[i][j].tileType != 0)
{
if (x.intersects(map[i][j].getGlobalBounds()))
kolX = true;
else if (y.intersects(map[i][j].getGlobalBounds()))
kolY = true;
std::vector<bullet>::iterator k = bullets.begin();
while (k != bullets.end())
{
if (k->getGlobalBounds().intersects(map[i][j].getGlobalBounds()))
{
k = bullets.erase(k);
ilosc--;
}
else
++k;
}
}
}
}
With that said, you might consider using std::remove_if() instead of manual erase() loops:
template<typename SourceType, typename TargetType>
struct intersectsBounds
{
TargetType &m_target;
intersectsBounds(TargetType &target) : m_target(target) {}
bool operator()(const SourceType &source) const
{
return source.getGlobalBounds().intersects(m_target.getGlobalBounds());
}
};
std::vector<enemy>::iterator i = ennemies.begin();
while (i != ennemies.end())
{
i->update(player);
if (player.getGlobalBounds().intersects(i->getGlobalBounds()))
{
player.kill();
}
std::vector<bullet>::iterator j = std::remove_if(bullets.begin(), bullets.end(), intersectsBounds(*i));
if (j != bullets.end())
{
i = ennemies.erase(i);
int numErased = std::distance(j, bullets.end());
bullets.erase(j, bullets.end());
ilosc -= numErased;
}
else
++i;
}
for (int i = 0; i < Level::LEVEL_HEIGHT; i++)
{
for (int j = 0; j < Level::LEVEL_WIDTH; j++)
{
if (level.tiles[i][j].tileType != 0)
{
if (x.intersects(map[i][j].getGlobalBounds()))
kolX = true;
else if (y.intersects(map[i][j].getGlobalBounds()))
kolY = true;
std::vector<bullet>::iterator k = std::remove_if(bullets.begin(), bullets.end(), intersectsBounds(map[i][j]));
if (k != bullets.end())
{
int numErased = std::distance(k, bullets.end());
bullets.erase(k, bullets.end());
ilosc -= numErased;
}
}
}
}

Related

How to fix signal SIGSEGV, Segmentation fault

I'm getting an error message in Codeblocks C++ 'Program received signal SIGSEGV, Segmentation fault' in comparison between a vector element and a size of vector of vectors inside for loop (line 133 if (parz_przestrzenie[i] != parz_dystanse[i].size())).
Could anyone tell me why?
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int bloki_parz[100000], bloki_nieparz[100000];
int silnia(int n)
{
int liczba = 1;
for (int i = 1; i <= n; i++)
{
liczba *= i;
}
return liczba;
}
int main()
{
int n, czapka, wolne_miejsca = 0, wynik = 1;
vector<int> parz, nieparz, parz_przestrzenie, nieparz_przestrzenie, parz_przestrzenie2, nieparz_przestrzenie2;
vector<vector<int>> parz_dystanse;
vector<vector<int>> nieparz_dystanse;
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> czapka;
if (i % 2 == 0)
{
parz.push_back(czapka);
}
else
{
nieparz.push_back(czapka);
}
}
int parz_size = parz.size(), nieparz_size = nieparz.size();
// sprawdzamy czy dane nie sÂą sprzeczne ; gdy zabraknie nam miejsc do rozmieszczania
vector<int> parz_duplicate = parz;
vector<int> nieparz_duplicate = nieparz;
parz_duplicate.erase(unique(parz_duplicate.begin(), parz_duplicate.end()), parz_duplicate.end());
nieparz_duplicate.erase(unique(nieparz_duplicate.begin(), nieparz_duplicate.end()), nieparz_duplicate.end());
int parz_dupl_size = parz_duplicate.size(), nieparz_dupl_size = nieparz_duplicate.size();
if (parz_size < nieparz_dupl_size)
{
cout << 0 << endl;
return 0;
}
if (nieparz_size < parz_dupl_size)
{
cout << 0 << endl;
return 0;
}
for (int i = 0; i < parz_size - 1; i++)
{
if (parz[i] == parz[i + 1])
{
bloki_parz[i + 1] = 1;
}
}
for (int i = 0; i < nieparz_size - 1; i++)
{
if (nieparz[i] == nieparz[i + 1])
{
bloki_nieparz[i] = 1;
}
}
for (int i = 0; i < parz_size; i++)
{
vector<int> bloczek;
for (int j = i; j < parz_size; j++)
{
if (parz[j] != parz[j + 1])
{
bloczek.push_back(parz[j]);
}
else
{
i += 1;
break;
}
}
if (bloczek.size() != 0)
{
parz_dystanse.push_back(bloczek);
}
}
int parz_dyst_size = parz_dystanse.size();
if (parz[parz_size - 1] != parz[parz_size - 2])
{
parz_dystanse[parz_dyst_size - 1].push_back(parz[parz_size - 1]);
}
for (int i = 0; i < nieparz_size; i++)
{
vector<int> bloczek;
for (int j = i; j < nieparz_size; j++)
{
if (nieparz[j] != nieparz[j + 1])
{
bloczek.push_back(nieparz[j]);
}
else
{
i += 1;
break;
}
}
if (bloczek.size() != 0)
{
nieparz_dystanse.push_back(bloczek);
}
}
int nieparz_dyst_size = nieparz_dystanse.size();
int current_wynik = 0;
for (int i = 0; i < nieparz_size; i++)
{
if (bloki_parz[i] == 0)
{
current_wynik++;
}
else
{
if (current_wynik != 0)
{
parz_przestrzenie.push_back(current_wynik);
}
current_wynik = 0;
}
}
parz_przestrzenie.push_back(current_wynik);
current_wynik = 0;
for (int i = 0; i < parz_size; i++)
{
if (bloki_nieparz[i] == 0)
{
current_wynik++;
}
else
{
if (current_wynik != 0)
{
nieparz_przestrzenie.push_back(current_wynik);
}
current_wynik = 0;
}
}
nieparz_przestrzenie.push_back(current_wynik);
int parz_przest_size = parz_przestrzenie.size(), nieparz_przest_size = nieparz_przestrzenie.size();
for (int i = 0; i < 1; i++)
{
if (parz_przestrzenie[i] != parz_dystanse[i].size())
{
wynik *= parz_przestrzenie[i];
wolne_miejsca++;
}
}
for (int i = 0; i < nieparz_przest_size; i++)
{
if (nieparz_przestrzenie[i] != nieparz_dystanse[i].size())
{
wynik *= nieparz_przestrzenie[i];
wolne_miejsca++;
}
}
cout << wynik * silnia(wolne_miejsca) << endl;
}
parz_dystanse is a vector of a vector. In this case the return value of parz_dystanse.size() is a long unsigned int, whereas an element of parz_przestrzenie is an int.
You need to make explicit that parz_dystanse.size() returns an int in order to make comparitions between integer expressions of different signedness.
This will fix that problem:
if (parz_przestrzenie[i] != (int)parz_dystanse[i].size())

Codewars UndefinedBehaviorSanitizer:DEADLYSIGNAL

When I use this code in Visual Studio, it works normally, but when I paste it to Codewars, this error appears. What did I suppose to do? Also, is the output function are valid?
This code for Skyscrapers 4x4 kata from codewars https://www.codewars.com/kata/5671d975d81d6c1c87000022/train/cpp
Also can change it to 6x6 (and any other size) easily.
STDERR
UndefinedBehaviorSanitizer:DEADLYSIGNAL
==1==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x0000ffffffff (pc 0x0000004254dd bp 0x000000000000 sp 0x7fff88975810 T1)
==1==The signal is caused by a WRITE memory access.
==1==WARNING: invalid path to external symbolizer!
==1==WARNING: Failed to use and restart external symbolizer!
#0 0x4254dc (/workspace/test+0x4254dc)
#1 0x42cf0a (/workspace/test+0x42cf0a)
#2 0x42b79e (/workspace/test+0x42b79e)
#3 0x42b31f (/workspace/test+0x42b31f)
#4 0x42af7b (/workspace/test+0x42af7b)
#5 0x42f2f5 (/workspace/test+0x42f2f5)
#6 0x42566d (/workspace/test+0x42566d)
#7 0x7f929bdf5bf6 (/lib/x86_64-linux-gnu/libc.so.6+0x21bf6)
#8 0x404249 (/workspace/test+0x404249)
UndefinedBehaviorSanitizer can not provide additional info.
==1==ABORTING
Code:
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
#include <iterator>
#include <string>
using namespace std;
void print(vector<int> array) {
for (unsigned int i = 0; i < array.size(); i++) cout << array[i] << " ";
}
int check_visible(vector<int> row) {
int visible = 0, current_height = 0;
for (unsigned int i = 0; i < row.size(); i++) {
if (row[i] > current_height) {
current_height = row[i];
visible++;
}
}
return visible;
}
class possible_vars {
public:
vector<int> vars;
/*possible_vars& operator= (const possible_vars& vars2)
{
vars = vars2.vars;
return *this;
}*/
possible_vars& operator= (const vector<int>& vars2)
{
vars = vars2;
return *this;
}
possible_vars(int bsize) {
for (int i = 0; i < bsize; i++) vars.push_back(i + 1);
}
possible_vars(vector<int> input) {
vars = input;
}
int size() {
return vars.size();
}
bool remove_variant(int num) {
bool is_changed = false;
for (unsigned int i = 0; i < vars.size(); i++) {
if (vars[i] == num) {
vars.erase(vars.begin() + i);
is_changed = true;
break;
}
}
return is_changed;
}
bool is_var_here(int var) {
if (find(vars.begin(), vars.end(), var) != vars.end()) return true;
else return false;
}
};
class skyscrapers {
public:
vector<vector<possible_vars>> solution;
vector<vector<short>> solution_static;
vector<int> clues;
vector<vector<int>> patterns;
vector<int> pattern;
int basic_size;
skyscrapers(int size_of_field) {
solution = vector<vector<possible_vars>>(size_of_field, vector<possible_vars>(size_of_field,possible_vars(size_of_field)));
solution_static = vector<vector<short>>(size_of_field, vector<short>(size_of_field, false));
clues = vector<int>(size_of_field * size_of_field);
basic_size = size_of_field;
}
vector<vector<possible_vars>> patterns_by_det;
vector<vector<possible_vars>> excluding_patterns;
void generate_excluding_base() {
possible_vars for_one_number(basic_size);
vector<possible_vars> for_one_pattern;
for (int i = 0; i < basic_size; i++) {
for_one_pattern.push_back(for_one_number);
}
for (int i = 0; i < basic_size; i++) {
excluding_patterns.push_back(for_one_pattern);
}
}
void generate_patterns() {
vector<int> base;
for (int i = 0; i < basic_size; i++) {
base.push_back(i + 1);
}
generate_patterns_re(base);
int seen;
patterns_by_det = vector<vector<possible_vars>>(basic_size);
for (unsigned int i = 0; i < patterns.size(); i++) {
seen = check_visible(patterns[i]);
patterns_by_det[seen - 1].push_back(possible_vars(patterns[i]));
}
generate_excluding_base();
for (unsigned int i = 0; i < patterns_by_det.size(); i++) {
for (unsigned int j = 0; j < patterns_by_det.size(); j++) {
for (unsigned int k = 0; k < patterns_by_det[i].size(); k++) {
excluding_patterns[i][j].remove_variant(patterns_by_det[i][k].vars[j]);
}
}
}
}
void generate_patterns_re(vector<int> possible_vars) {
vector<int> next;
if (possible_vars.size() > 1) {
for (unsigned int i = 0; i < possible_vars.size(); i++) {
pattern.push_back(possible_vars[i]);
next = possible_vars;
next.erase(next.begin() + i);
generate_patterns_re(next);
pattern.pop_back();
}
}
else {
pattern.push_back(possible_vars[0]);
patterns.push_back(pattern);
pattern.pop_back();
}
}
vector<possible_vars*> get_row(int row_index) {
vector<possible_vars*> row;
possible_vars* cell;
if (row_index / basic_size == 0) {
for (int i = 0; i < basic_size; i++) {
cell = &solution[i][row_index % basic_size];
row.push_back(cell);
}
}
else if (row_index / basic_size == 1) {
for (int i = 0; i < basic_size; i++) {
cell = &solution[row_index % basic_size][basic_size - 1 - i];
row.push_back(cell);
}
}
else if (row_index / basic_size == 2) {
for (int i = 0; i < basic_size; i++) {
cell = &solution[basic_size - 1 - i][basic_size - 1 - row_index % basic_size];
row.push_back(cell);
}
}
else if (row_index / basic_size == 3) {
for (int i = 0; i < basic_size; i++) {
cell = &solution[basic_size - 1 - row_index % basic_size][i];
row.push_back(cell);
}
}
return row;
}
vector<short*> get_static_row(int row_index) {
vector<short*> row;
short* cell;
if (row_index / basic_size == 0) {
for (int i = 0; i < basic_size; i++) {
cell = &solution_static[i][row_index % basic_size];
row.push_back(cell);
}
}
else if (row_index / basic_size == 1) {
for (int i = 0; i < basic_size; i++) {
cell = &solution_static[row_index % basic_size][basic_size - 1 - i];
row.push_back(cell);
}
}
else if (row_index / basic_size == 2) {
for (int i = 0; i < basic_size; i++) {
cell = &solution_static[basic_size - 1 - i][basic_size - 1 - row_index % basic_size];
row.push_back(cell);
}
}
else if (row_index / basic_size == 3) {
for (int i = 0; i < basic_size; i++) {
cell = &solution_static[basic_size - 1 - row_index % basic_size][i];
row.push_back(cell);
}
}
return row;
}
void remove_all_vars(int y, int x) {
for (int i = 0; i < basic_size; i++) {
if (i != x) solution[y][i].remove_variant(solution[y][x].vars[0]);
}
for (int i = 0; i < basic_size; i++) {
if (i != y) solution[i][x].remove_variant(solution[y][x].vars[0]);
}
}
bool normalize() {
bool is_changed = false;
for (int i = 0; i < basic_size; i++) {
for (int j = 0; j < basic_size; j++) {
if (solution_static[i][j] == false and solution[i][j].vars.size() == 1) {
solution_static[i][j] = true;
remove_all_vars(i, j);
is_changed = true;
}
}
}
return is_changed;
}
bool add_obvious() {
bool is_changed = false;
map<int, int> counting;
for (int i = 0; i < basic_size; i++) counting.insert(pair<int, int>(i + 1, 0));
for (int i = 0; i < basic_size; i++) {
for (int j = 1; j <= basic_size; j++) counting[j] = 0;
for (int j = 0; j < basic_size; j++) {
for (int k = 0; k < solution[i][j].size(); k++) {
counting[solution[i][j].vars[k]] += 1;
}
}
for (int k = 1; k <= basic_size; k++) {
if (counting[k] == 1) {
for (int j = 0; j < basic_size; j++) {
if (solution_static[i][j] == false and solution[i][j].is_var_here(k)) {
solution[i][j].vars = { k };
solution_static[i][j] = true;
remove_all_vars(i, j);
is_changed = true;
}
}
}
}
}
for (int j = 0; j < basic_size; j++) {
for (int j = 1; j <= basic_size; j++) counting[j] = 0;
for (int i = 0; i < basic_size; i++) {
for (int k = 0; k < solution[i][j].size(); k++) {
counting[solution[i][j].vars[k]] += 1;
}
}
for (int k = 1; k <= basic_size; k++) {
if (counting[k] == 1) {
for (int i = 0; i < basic_size; i++) {
if (solution_static[i][j] == false and solution[i][j].is_var_here(k)) {
solution[i][j].vars = { k };
solution_static[i][j] = true;
remove_all_vars(i, j);
is_changed = true;
}
}
}
}
}
return is_changed;
}
bool fix_matrix() {
bool is_changed = false, is_changed_global = false;
do {
is_changed = normalize();
is_changed_global += is_changed;
} while (is_changed == true);
do {
is_changed = add_obvious();
is_changed_global += is_changed;
} while (is_changed == true);
return is_changed_global;
}
bool use_excluding_patterns() {
bool is_changed = false;
vector<possible_vars*> row;
int current_value;
for (unsigned int curr_clue = 0; curr_clue < clues.size(); curr_clue++) {
if (clues[curr_clue] != 0) {
row = get_row(curr_clue);
current_value = clues[curr_clue] - 1;
for (unsigned int i = 0; i < excluding_patterns[current_value].size(); i++) {
for (int j = 0; j < excluding_patterns[current_value][i].size(); j++) {
is_changed += row[i]->remove_variant(excluding_patterns[current_value][i].vars[j]);
}
}
}
}
return is_changed;
}
bool use_patterns() {
bool is_changed = false, is_suitable;
vector<possible_vars*> row;
vector<short*> static_row;
int current_value;
vector<possible_vars> current_patterns;
for (unsigned int curr_clue = 0; curr_clue < clues.size(); curr_clue++) {
if (clues[curr_clue] != 0) {
row = get_row(curr_clue);
static_row = get_static_row(curr_clue);
current_value = clues[curr_clue] - 1;
current_patterns = patterns_by_det[current_value];
for (unsigned int i = 0; i < current_patterns.size(); i++) {
//for (int print = 0; print < current_patterns[i].size(); print++) cout << current_patterns[i].vars[print] << " ";
//cout << endl;
for (int j = 0; j < current_patterns[i].size(); j++) {
is_suitable = row[j]->is_var_here(current_patterns[i].vars[j]);
// cout << j+1 << "-> " << is_suitable << endl;
if (is_suitable == false) {
current_patterns.erase(current_patterns.begin() + i);
i--;
//cout << endl << "Erased, now current patterns:" << endl;
/*for (int print1 = 0; print1 < current_patterns.size(); print1++) {
for (int print2 = 0; print2 < current_patterns[print1].size(); print2++) cout << current_patterns[print1].vars[print2] << " ";
cout << endl;
}
cout << endl;*/
break;
}
}
}
if (current_patterns.size() == 1) {
for (unsigned int i = 0; i < row.size(); i++) {
if (*static_row[i] == false) {
*static_row[i] = true;
is_changed = true;
*row[i] = possible_vars(vector<int>(1, current_patterns[0].vars[i]));
}
}
}
}
}
return is_changed;
}
void print() {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
for (int k = 0; k < solution[i][j].size(); k++) cout << solution[i][j].vars[k];
cout << " ";
}
cout << endl;
}
cout << endl;
}
};
int** SolvePuzzle(int* clues) {
skyscrapers result(4);
result.generate_patterns();
for (int i = 0; i < 16; i++) {
result.clues[i] = clues[i];
}
bool is_changed = true;
result.use_excluding_patterns();
result.fix_matrix();
while (is_changed) {
is_changed = result.use_patterns();
is_changed += result.fix_matrix();
}
int** answer[4][4];
for (unsigned int i = 0; i < result.solution.size(); i++) {
for (unsigned int j = 0; j < result.solution[i].size(); j++) {
*answer[i][j] = &result.solution[i][j].vars[0];
}
}
return **answer;
}
This block of code appears suspicious for several reasons:
int** answer[4][4];
for (unsigned int i = 0; i < result.solution.size(); i++) {
for (unsigned int j = 0; j < result.solution[i].size(); j++) {
*answer[i][j] = &result.solution[i][j].vars[0];
}
}
return **answer;
&result.solution[i][j].vars[0] is a pointer to something inside that result object. As soon as the function returns, result will destruct and the pointers assigned to answer[i][j] is no longer valid when the function returns.
Also, returning **answer is really suspicious. With regards to a local 2-d array, this statement would in essence only return the int** inside answer[0][0]. None of the other values inside answer would be passed back - even if result wasn't destructing.
The problem is that you made a 4x4 array of int**. Here is the fixed code:
int** answer = new int*[4];
for (unsigned int i = 0; i < result.solution.size(); i++) {
answer[i] = new int[4];
for (unsigned int j = 0; j < result.solution[i].size(); j++) {
answer[i][j] = result.solution[i][j].vars[0];
}
}

C++ issue with 2D vector: When executed, your code modified memory in a way that was illegal

this is my first time posting a question in SO. I've been working in a program that tests if there are four consecutive numbers of the same value. I am using Visual Studio as my IDE and my code is compiling good, the problem is that in my class, we are posting the code through a website (Pearson) which tests if the code is correct or not. The problem that is giving me is the following: "When executed, your code modified memory in a way that was illegal. Common causes for this problem include array indexing errors and pointer operation (*) errors." My understanding of pointers is very low, but I don't see anything wrong with my code.
#include <iostream>
#include <vector>
using namespace std;
int row = 6;
int col = 7;
bool checkRow(vector<vector<int>> v) {
int count = 0;
for (int i = 0; i < row; i++) {
for (int j = 1; j < col; j++) {
if (a[i][j - 1] == a[i][j]) {
count++;
}
else {
count = 0;
} if (count == 3) {
return true;
}
} count = 0;
} return false;
}
bool checkCol(vector<vector<int>> v) {
int count = 0;
for (int i = 0; i < row; i++) {
for (int j = 1; j < col; j++) {
if (a[j - 1][i] == a[j][i]) {
count++;
}
else {
count = 0;
} if (count == 3) {
return true;
}
} count = 0;
} return false;
}
bool diagonalOne(vector<vector<int>> v) {
int count = 0;
if (row < 4 || col < 4) {
return false;
}
else {
for (int k = 3; k < col; k++) {
for (int i = 1, j = k; j > 0; i++, j--) {
if (a[i][j - 1] == a[i - 1][j]) {
count++;
}
else {
count = 0;
} if (count == 3) {
return true;
}
} count = 0;
}
int i = 1;
int j = row - 1;
int k = 0;
count = 0;
for(int i = 1; row - i > 3; i++){
k = i;
for (j = col - 1; j - 1 > i; j--, k++) {
if (a[k][j] == a[k + 1][j - 1]) {
count++;
}
else {
count = 0;
} if (count == 3) {
return true;
}
} count = 0;
} return false;
}
}
bool diagonalTwo(vector<vector<int>> v) {
int count = 0;
int i, j, k;
if (row < 4 || col > 4) {
return false;
}
else {
for (i = 1; i < col - i; i++) {
k = 0;
for (j = i; j < row; j++, k++) {
if (a[k][j] == a[k + 1][j + 1]) {
count++;
}
else {
count = 0;
} if (count == 3) {
return true;
}
} count = 0;
for (i = 0; i < row - 3; i++) {
k = i;
for (j = 0; j + 1 < row - i; j++, k++) {
if (a[k][j] == a[k + 1][j + 1]) {
count++;
}
else {
count = 0;
} if (count == 3) {
return true;
}
}
} cout << endl;
count = 0;
} return false;
}
}
bool isConsecutiveFour(vector<vector<int>> & values) {
if (checkRow(values) == true) {
return true;
} if (checkCol(values) == true) {
return true;
} if (diagonalOne(values) == true) {
return true;
} if (diagonalTwo(values) == true) {
return true;
} return false;
}
int main()
{
int i = 0;
int j = 0;
vector<vector<int>>a(row);
for (i = 0; i < row; i++) {
a[i] = vector<int>(col);
for (j = 0; j < col; j++) {
cin >> a[i][j];
}
}
for (i = 0; i < row; i++) {
for (j = 0; j < col; j++) {
cout << a[i][j] << " ";
} cout << endl;
}
if (isConsecutiveFour(a) == true) {
cout << "The array has consecutive fours" << endl;
}
else {
cout << "The array does not have consecutive fours" << endl;
}
system("PAUSE");
return 0;
}
The bounds on the loops inside your checkCol function are wrong, that's why a segmentation fault is occurring. Make it :
for (int i = 0; i < col; i++) {
for (int j = 1; j < row; j++) {
Same error is with diagonalOne function. Make it :
for (int k = 3; k < row; k++) {
Advice : Avoid using using namespace std and system("PAUSE"), and make yourself familiar with debugger present in VS.

Vector subscription out of range error c++

I am trying to create a simulation of conway's game of life.
I keep getting a "vector subscript out of range" error after about 300 generation and I don't understand the reason. From what I could gather it's caused by using an invalid index. The most likely section is the first part of the draw function where I find empty rows and replace them with "\n" to save time.
I've started learning to code not too long ago so I may be making baby mistakes.
Edit: visual studio point the error after the third for loop in the frame function, on if (emptyRows[m] == i)
Here's the full code :
#include <array>
#include <time.h>
#include <vector>
const int WIDTH = 150;
const int HEIGHT = 50;
bool table[WIDTH][HEIGHT];
bool tableNew[WIDTH][HEIGHT];
std::string buffer;
int total;
int counter = 0;
std::vector<int> emptyRows;
int numberOfNeighbours(int Y, int X) {
if (X == 0 || Y == 0 || X == WIDTH || Y == HEIGHT)
return 2;
total = 0;
for (int i = -1; i < 2; i++) {
for (int j = -1; j < 2; j++) {
if (table[X + j][Y + i] == true)
total++;
}
}
total -= table[X][Y];
return total;
}
void draw() {
srand((int)time(0));
int m = 0;
bool check = 0;
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
if (table[j][i] == 1)
check = 1;
}
if (check == 0)
emptyRows.push_back(i);
else
check = 0;
}
for (int i = 0; i < HEIGHT; i++) {
if (emptyRows.size() >= 1) {
if (emptyRows[m] == i) {
buffer.append("\n");
m++;
continue;
}
}
for (int j = 0; j < WIDTH; j++) {
if (table[j][i] == 1) buffer.push_back('#');
else buffer.push_back(' ');
}
buffer.append("\n");
}
std::cout << buffer;
std::cout << std::endl << "Generazione numero:" << counter;
emptyRows.erase(emptyRows.begin(), emptyRows.end());
buffer.erase(buffer.begin(), buffer.end());
m = 0;
}
void reset() {
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
table[j][i] = tableNew[j][i];
}
}
}
void logic() {
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
int k = numberOfNeighbours(i, j);
if (table[j][i] == 0 && k == 3)
tableNew[j][i] = 1;
else if (table[j][i] == 1 && k != 2 && k != 3)
tableNew[j][i] = 0;
else
tableNew[j][i] = table[j][i];
}
}
}
int main(){
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
if ((rand() % 2) == 1)
table[j][i] = 1;
}
}
while (true) {
counter++;
draw();
logic();
reset();
system("cls");
}
return 0;
}

Suffix Array Algorithm Implementation

I am currently trying to implement generalized suffix array according to the algorithm described in this paper: paper.
However I am stuck at the moment with implementation of the sorting algorithm in chapter 2.
My current c++ code looks roughly like this (my alphabet is lowercase English letters):
std::vector<std::pair<int,int>> suffix_array(const std::vector<std::string>& ss) {
std::vector<std::vector<std::pair<int,int>>> tmp(26);
size_t n = 0;
for (size_t i = 0; i < ss.size(); i++) {
if (ss[i].length() > n) {
n = ss[i].length();
}
for (size_t j = 0; j < ss[i].length(); j++) {
tmp[ss[i][j] - 'a'].push_back(std::make_pair(i,j));
}
}
// initialize pos
std::vector<std::pair<int,int>> pos;
std::vector<bool> bh;
for (auto &v1 : tmp) {
bool b = true;
for (auto &p: v1) {
pos.push_back(p);
bh.push_back(b);
b = false;
}
}
// initialze inv_pos
std::map<std::pair<int,int>,int> inv_pos;
for (size_t i = 0; i < pos.size(); i++) {
inv_pos[pos[i]] = i;
}
int H = 1;
while (H <= n) {
std::vector<int> count(pos.size(), 0);
std::vector<bool> b2h(bh);
for (size_t i = 0, j = 0; i < pos.size(); i++) {
if (bh[i]) {
j = i;
}
inv_pos[pos[i]] = j;
}
int k = 0;
int i = 0;
while (i < pos.size()) {
int j = k;
i = j;
do {
auto t = std::make_pair(pos[i].first, pos[i].second - H);
if (t.second >= 0) {
int q = inv_pos[t];
count[q] += 1;
inv_pos[t] += (count[q] - 1);
b2h[inv_pos[t]] = true;
}
i++;
} while (i < pos.size() && !bh[i]);
k = i;
i = j;
do {
auto t = std::make_pair(pos[i].first, pos[i].second - H);
if (t.second >= 0) {
int q = inv_pos[t];
if ((j <= q) && (q < k) && (j <= (q+1)) &&
((q+1) < k) && b2h[q+1]) {
b2h[q+1] = false;
}
}
i++;
} while (i < k);
}
bh = b2h;
for (auto &x : inv_pos) {
pos[x.second] = x.first;
}
H *= 2;
}
return pos;
}
At the moment, I get garbage results with my implementation. And I don't quite understand from the algorithm description in the paper how inv_pos is correctly updated after each stage...
If someone can spot what is wrong with my implementation and show me the right direction with brief explanation, I would be really grateful.