I made a "game of life" program, where you insert the size, the living cells and the speed of the game. Unfortunately my program isn't working. I narrowed down the problem to the vector> rules function, and I guess it has to do something with too high or low numbers. this code compiles, but as soon as I come to the rules part I get the following error:
==3944==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x604000000100 at pc 0x000000518258 bp 0x7ffdd648f5d0 sp 0x7ffdd648f5c8
I tried to change the unsigned integer values to normal integers but theres just a warning popping up then. I made everything else work but I cant seem to find a way to make this work. I appreciate any help!
If it helps, I work on a ubuntu operating system, with clang as my compiler.
#include <iostream>
#include <stdexcept>
#include <cmath>
#include <vector>
#include <unistd.h>
using namespace std;
void rowsandcolumns (int row, int column) {
int rowwhole = floor (row);
int columnwhole = floor (column);
if (row <=0 || column <=0 || row != rowwhole || column != columnwhole) {
throw runtime_error ("Nur positive ganze Zahlen erlaubt");
}
}
vector<vector<int>> rules (vector<vector<int>> cleanBoard, int row, int column, vector<vector<int>> secondBoard) {
for (int i = 1; i <= row+1; i++) {
for (int j = 1; j <= column+1; j++) {
int x;
int a = cleanBoard [i-1][j-1];
int b = cleanBoard [i][j-1];
int c = cleanBoard [i+1][j-1];
int d = cleanBoard [i-1][j];
int e = cleanBoard [i+1][j];
int f = cleanBoard [i-1][j+1];
int g = cleanBoard [i][j+1];
int h = cleanBoard [i+1][j+1];
int mitte = cleanBoard [i][j];
cout << cleanBoard[i][j];
x = a+b+c+d+e+f+g+h;
if (x < 2 && mitte == 1) {
secondBoard [i][j] = 0;
}
else if ((mitte == 1 && x == 2) || x == 3) {
secondBoard [i][j] = 1;
}
else if (mitte == 1 && x > 3) {
secondBoard [i][j] = 0;
}
else if (mitte == 0 && x == 3) {
secondBoard [i][j] = 1;
}
else break;
}
}
return secondBoard;
}
double gamespeed() {
double speed;
cout << "Geben sie nun die Geschwindigkeit ein, mit welcher sich 'Game of Life' entwickeln soll. (Empfohlen 0.5 Sekunden bis 2 Sekunden)\n";
cin >> speed;
cout << '\n';
return speed;
}
int main () {
//initialisierung der wichtigen Variablen
int alive = 1;
int dead = 0;
double row, column, x, y, speed;
//Eingabe der Reihen und Spalten und Check, ob dies erlaubt ist
cout << "Geben sie die Dimensionen row (Zeilen) und column (Spalten) für Conways 'Game of Life' an! (Ganze positive Zahlen)\n";
cin >> row >> column;
rowsandcolumns(row, column);
//Erstellung des nxm Feldes
vector<int> v(column);
vector<vector<int>> cleanBoard(row, v);
//Erstellung des Spielfeldes, wo jede Zelle tot ist
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
cleanBoard[i][j] = dead;
cout << cleanBoard[i][j] << " ";
}
cout << endl;
}
//Eingabe der eigenen lebenden Zellen und Check, ob eine richtige Zahl eingegeben wurde
do {
cout << "Geben sie nun die Koordinaten ein, an welcher Stelle sie eine lebende Zelle platzieren wollen. Vorher Zeile, dann Spalte! (Geben sie mindestens einmal 0 ein, um das Spiel zu starten)\n";
cin >> x >> y;
int newx = floor (x);
int newy = floor (y);
if (x < 0 || y < 0 || newx != x || newy != y || x > row || y > column) {
throw runtime_error ("Nur positive ganze Zahlen zwischen 1 und den eingegebenen Dimensionen möglich.");
}
if (x != 0 || y != 0){
x -= 1;
y -= 1;
cleanBoard[x][y] = alive;
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
cout << cleanBoard[i][j] << " ";
}
cout << endl;
}
x += 1;
y += 1;
}
} while (x != 0 || y != 0);
cout << '\n';
//Zeiteingabe
speed = gamespeed();
//Start des Spiels und Spielablauf
vector<vector<int>> secondBoard;
for (int u = 1; 0 < u; u--) {
rules(cleanBoard, row, column, secondBoard);
for (unsigned i = 0; i < secondBoard.size(); i++) {
for (unsigned j = 0; j < secondBoard[i].size(); j++) {
cout << secondBoard[i][j] << " ";
}
cout << endl;
}
cleanBoard = secondBoard;
cout << "STRG+Z zum abbrechen";
usleep(speed*1000);
}
return 0;
}
The problem is in the rules function where you have the two for-loops.
for (int i = 1; i <= row+1; i++) {
for (int j = 1; j <= column+1; j++) {
Some of the calls to cleanBoard are out of bounds. if rows is 3,int i will go until it is no longer <= 3+1. So, the last loop will have int i = 4. with this line...
int c = cleanBoard [i+1][j-1];
You're trying to do cleanBoard[5][j-1], but cleanBoard[5] doesn't exist, it is only initialized up to [row][column]. The fix would be something like this:
for (int i = 1; i <= row-1; i++) {
for (int j = 1; j <= column-1; j++) {
Edit: Theres also another bug somewhere, I'm not so sure about how to fix it though. The error I got was
Program received signal SIGSEGV, Segmentation fault.
0x000055555555631a in std::vector<int, std::allocator<int> >::operator[] (
this=0x18, __n=1) at /usr/include/c++/9/bits/stl_vector.h:1043
1043 return *(this->_M_impl._M_start + __n);
Instead of just working in code, draw out your board visually so you can see what you are trying to achieve
c0 c1 c2 ... cn cn+1
r0 : :___:___:...:___: :
r1 : |___|___|...|___| :
r2 : |___|___|...|___| :
: : : : : : :
: :___:___: :___: :
rn : |___|___|...|___| :
rn+1 : : : : : :
You can immediately see that the last column is cn + 1; therefore the size of the vector is cn + 2.
Also, when the for loop does the checks, it only needs to go from 1 to cn: not cn+1 since the code searches all the cells around the current cell and the board only extends from 1 to cn. Similar problem with the rows.
When debugging manually, you can also use the diagram to work out which cell it is checking.
a d f
b g
c e h
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.