I have the following code for a board game program that I am making. The function "copyMap" simply copies the contents of the first array map to the second array map_copy. In the function "solver", I have a loop that iterates over the game grid, and for each cell, call copyMap.
The issue is, when solver is called, it runs for 1 iteration then promptly crashes the program. Moreover, the iterators, x_pos and y_pos, which are supposed to start at 0 and 0, gets changed to 2 and 5 after calling copyMap and before the program crashes.
void copyMap(int map[][WIDTH], int map_copy[][WIDTH], int rows_to_copy) {
// copy the contents of the first rows_to_copy rows of map to map_copy
for( int i = 0 ; i < rows_to_copy ; i++ ) {
for( int j = 0 ; j < WIDTH ; j++ ) {
map_copy[i][j] = map[i][j];
cout<<i<<" "<<j<<endl;
}
}
}
int solver(int map[][WIDTH]) {
int map_copy[HEIGHT][WIDTH];
for(int x_pos = 0 ; x_pos < HEIGHT ; x_pos++ ) {
for(int y_pos = 0 ; y_pos < WIDTH ; y_pos++ ) {
copyMap(map, map_copy, MAX_ROWS);
cout<<x_pos<<" "<<y_pos<<endl;
}
}
}
This is the console output: (For the first iteration of the loop)
0 0
0 1
0 2
...
81 8
2 5
The game grid has 81 rows and 9 columns, so copyMap prints 0 0, 0 1, ..., 81 8.
Then, solver prints 2 5. However, the iterators are still supposed to be 0 0.
The iterators are not passed to the function copyMap at all. Why are their values being changed, and why is my program crashing?
I would appreciate any help on this issue, thank you.
Copymap iterates through each element. I don't think you need to call it inside a nested loop inside solver. You should take it outside of the loop and set a breakpoint inside the loop to watch x_pos and y_pos.
Solved, turns out map has 81 rows and 9 columns but map_copy only has 9 rows and 9 columns, so copyMap tried to access out-of-bounds memory locations.
Related
#include <iostream>
#include <vector>
using namespace std;
int main(void)
{
vector<vector<int> > matrix;
matrix.resize(3, vector<int>(4, 1));
for (size_t i = 0; i < 3; i++)
{
for (size_t j = 0; j < 4; j++)
{
cout << matrix[i][j];
}
cout << endl;
}
matrix.resize(5, vector<int>(7, 0));
for (size_t i = 0; i < 5; i++)
{
for (size_t j = 0; j < 7; j++)
{
cout << matrix[i][j];
}
cout << endl;
}
return 0;
}
'''
As far as I know, when we are resizing a vector using "resize()" over than original capacity, values in original space will remain and new values are assigned to new space.
In the line matrix.resize(5, vector(7, 0)); If we execute that line I thought matrix would be like
1111000
1111000
1111000
0000000
0000000
something like this.
But the programs stops,
I want to know why it won't working.
matrix.resize(5, vector<int>(7, 0));
only add new vector of size 7 not modifying actual vector.
Just resize actual vectors to 7 with:
for (auto &row: matrix) row.resize(7);
so now is working:
1111000
1111000
1111000
0000000
0000000
i tested your codes using an online compiler https://onlinegdb.com/BkwcGuAAD
your columns are not resized (only the rows are resized). running your current code yields
1 1 1 1 0 0 33
1 1 1 1 0 0 33
1 1 1 1 0 0 49 << notice some columns have random numbers?
0 0 0 0 0 0 0
0 0 0 0 0 0 0
try resizing the columns too
matrix[0].resize(7,0);
matrix[1].resize(7,0);
matrix[2].resize(7,0);
matrix.resize(5, vector<int>(7, 0));
you should get something like the following
1 1 1 1 0 0 0
1 1 1 1 0 0 0
1 1 1 1 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
By the C++ Reference
(http://www.cplusplus.com/reference/vector/vector/resize/)
void resize (size_type n);
void resize (size_type n, const value_type& val);
Resizes the container so that it contains n elements.
If n is smaller than the current container size, the content is reduced to its first n elements, removing those beyond (and destroying them).
If n is greater than the current container size, the content is expanded by inserting at the end as many elements as needed to reach a size of n. If val is specified, the new elements are initialized as copies of val, otherwise, they are value-initialized.
If n is also greater than the current container capacity, an automatic reallocation of the allocated storage space takes place.
Notice that this function changes the actual content of the container by inserting or erasing elements from it.
I thought Compiler will understand if I put more longer vector inside of "val".
That is, I thought it would understand this kind of increased "n".
But Compiler will only watch whether "n" parameter itself is changed or not.
Because of this reason, my code wouldn't work properly.
if you want to increase size of vector using size() function, note that you should resize original row values on your hand.
i am new at c++, i am trying to make a program that can input a matriks from ftitikberat.txt with this format:
id[...] -> matriks id
row[id[...]] -> number of matriks rows
coloumns[id[...]] -> number of matriks coloumns
matriks[id[...]] [row[id[...]]] [col[id[...]]] -> matriks
name[id[...]] -> matriks name
the program can be compiled, but when i try to input ftitikberat.txt its always crash
here's the code:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
int row[1000];
int col[1000];
int matriks[1000][4][4];
int id[1000];
int i,j,k;
string name[1000];
ifstream ifile("ftitikberat.txt");
for(i=1; i<=1000; i++)
{
ifile>>id[i]>>name[i]>>row[i]>>col[i];
for(j=1; j<=row[id[i]]; j++)
{
for(k=1; k<=col[id[i]]; k++)
{
ifile>>matriks[id[i]][j][k];
}
}
}
ifile.close();
and for the text:
1 null 1 1 0
2 null 1 1 0
3 null 1 1 0
4 null 1 1 0
.
. //until
.
998 null 1 1 0
999 null 1 1 0
1000 null 1 1 0
i have tried to change the text to:
...
998 null 1 1 0 1
...
and when i try to compile and run it, the program work just fine, except i cant use id 999 and 1000 because it just messed up, same when i tried to change the text at id 997 (997 null 1 1 0 1) and program didn't crash but i cant use id 998,999,1000
i have also tried to change maximal array one by one, and the program didn't crash when i change maximal array of (id and name) from 1000 to 1001, but i dont know why its work
can somebody please explain me why the program (before i changing text/maximal array) didn't work? i staring at this simple program like hours, but still don't know where the problem is :')
Array indexes go from 0 to size-1, not from 1 to size. So you're accessing outside the arrays when you do:
for(i=1; i<=1000; i++)
it should be:
for (i = 0; i < 1000; i++)
Your other loops should also start from 0 and use < instead of <=.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am creating a Minesweeper game. However, while testing the generating function, It malfunctions almost always (if not always), and I do not understand why.
Here is my code:
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
struct board {
int width=9, mines=10;
char board[9][9];
/* char board[][]
* -1 = Mine
* 0 = No mines near
* 0+ = x amount of mines are near
*/
};
struct point {
int x,y;
};
board newBoard(){
board board1;
point randPoint;
for(int i=0;i<board1.width;i++){
for(int j=0;j<board1.width;j++) board1.board[i][j]=0; // Initialize array
}
for(int i=0;i<board1.mines;i++){
randPoint.x=rand()%board1.width, randPoint.y=rand()%board1.width; // Where will the mine go?
if(board1.board[randPoint.x][randPoint.y]!=-1){ // If not already a mine
board1.board[randPoint.x][randPoint.y]=-1; //make a mine
} else i--; //else don't count this
}
for(int i=0;i<board1.width;i++){
for(int j=0;j<board1.width;j++){
if(board1.board[i][j]==-1) { // If mine exists
// The if checks preceding the ++'s are to prevent out of bounds erors
if (j-1>=0) board1.board[i][j-1]++;
if (j+1<board1.width) board1.board[i][j+1]++;
if (i-1>=0) board1.board[i-1][j]++;
if (i+1<board1.width) board1.board[i+1][j]++;
if ((i-1>=0) && (j-1>=0)) board1.board[i-1][j-1]++;
if ((i-1>=0) && (j+1<board1.width))board1.board[i-1][j+1]++;
if ((i+1<board1.width) && (j-1>=0))board1.board[i+1][j-1]++;
if ((i+1<board1.width) && (j+1<board1.width))board1.board[i+1][j+1]++;
}
}
}
return board1;
}
int main() {
board boardGame=newBoard();
printf("- ");
for(int i=0;i<boardGame.width;i++) printf("%i ",i+1);
printf("\n\n");
for(int i=0;i<boardGame.width;i++){
printf("%i. ",i+1);
for(int j=0;j<boardGame.width;j++) if (boardGame.board[i][j]==-1) {
printf(" X");
} else {
printf(" %i", boardGame.board[i][j]);
}
printf("\n");
}
return 0;
}
This produces:
- 1 2 3 4 5 6 7 8 9
1. 0 0 0 0 1 X 1 0 0
2. 1 1 0 0 2 2 2 1 1
3. X 2 1 1 1 X 1 1 X
4. 1 2 X 0 1 1 0 1 1
5. 0 1 1 1 0 0 0 0 0
6. 0 0 0 0 1 1 1 0 0
7. 0 0 1 1 2 X 1 0 0
8. 1 1 2 X 2 1 1 0 0
9. 1 X 2 1 1 0 0 0 0
As you most likely already know, in the game of minesweeper, there is mines (in this case will they will be marked as X), and all nearby grid points are the number of mines near it (if you are still unfamiliar with it this page may of use). As you can see, the numbers at 4,7 and 4,4 are incorrect.
I do not know why this is this way. Could someone aid my understanding in this, and tell my how to to fix this?
Also, I just noticed that this produces the same output every time it is run. Why?
Ioums is correct, you are not checking to see if a cell is a mine before incrementing it. However, with the way that your code is currently set up, this will mean adding a check that the cell does not equal -1 in every single if statement. You should consider creating a function to safely increment a cell if it is within bounds and not a mine, like so:
void safeIncrement(int x, int y, board& b)
{
if(x >= 0 && y >= 0 && x < b.width && y < b.width && b.board[x][y] != -1)
{
b.board[x][y]++;
}
}
This means that you can replace your if statements with:
safeIncrement(i-1,j,board1);
safeIncrement(i-1,j-1,board1);
safeIncrement(i-1,j+1,board1);
safeIncrement(i,j-1,board1);
safeIncrement(i,j+1,board1);
safeIncrement(i+1,j,board1);
safeIncrement(i+1,j-1,board1);
safeIncrement(i+1,j+1,board1);
Which is much more readable in my opinion. Additionally, since the function doesn't increment the cell if it is a mine, you could also replace the if statements with the following code!
for(int a=-1; a<=1; a++)
{
for(int b=-1; b<=1; b++)
{
safeIncrement(i+a,j+b, board1);
}
}
The problem happens when 2 mines are close together: when you're adding to the mine count, you don't check if that square has a mine.
Suppose you get a mine on (0, 0) and another on (0, 1). When you're adding to the mine count around (0, 0), you accidentally also add to the mine in (0, 1), changing it from -1 to 0. It also makes the second mine being processed disappear.
I suggest using another number to signal a mine, like -999, and check if the number is negative when looking for them. It's easier than adding another condition for all if clauses you already have.
Please forgive me if the title is wrong, or, does not explain the problem correctly.
I'm trying to calculate the LU Decomposition of a matrix. Give the matrix M:
M = [1 2 3],
[1 2 3],
[3 3 0]
Now I'm following some code that was written here: Link
It uses j i in order to calculate the lower decomposition. When I try this approach, I keep getting a "Runtime error time: 0 memory: 3276 signal:11"
The thing that I do not understand is the fact that, when I output i, j inside of the 3x3 loop, I got:
i, j =
0 0 1 0 2 0
0 1 1 1 2 1
0 2 1 2 2 2
Then when output the indexes of j,i I get:
j, i =
0 0 0 1 0 2
1 0 1 1 1 2
2 0 2 1 2 2
Which seems right in terms of the order [0][0][0][2].........[2][2] so why can I not access this, inside my vector?
The code that I have written so far is:
void lu_decomposition(const std::vector<std::vector<double> > &vals)
{
std::vector<std::vector<double> > lower(3);
for(unsigned i=0; (i < 3); i++)
{
lower[i].resize(3);
for(unsigned j=0; (j < 3); j++)
{
if (j < i)
{
lower[j][i] = 0; // This is ok
}else{
lower[j][i] = vals[j][i]; // This is the runtime error
}
}
std::cout << std::endl;
}
}
The code is also visible on ideone
Let's concentrate on these lines:
lower[i].resize(3);
//...
lower[j][i] = vals[j][i];
Is the problem clear now? You're resizing lower[i], but then you're accessing lower[j] even for j > i, which has not been resized yet. If you need to access the matrix in this fashion, you'll have to preallocate it beforehand. That means to drop the resize call and instead initialise the variable like this:
std::vector<std::vector<double> > lower(3, std::vector<double>(3));
When the following program is fead the following input (reading from cin):
1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1
The output is surprising:
1 1 1 2 2 1 1 1 1 1 1 1 1 1 1 1
#include<iostream>
using namespace std;
int main()
{
int arey[3][3];
int i,j;
for(j=0;j<=3;j++)
{
for(i=0;i<=3;i++)
{
cin>>arey[j][i];
}
}
arey[0][0]=1;
arey[3][3]=1;
i=0,j=0;
for(j=0;j<=3;j++)
{
for(i=0;i<=3;i++)
{
cout<<arey[j][i];
}
}
return 0;
}
Can someone explain what I should change to get the same output as the input?
Is the matrix 3x3 or 4x4?
you created 3x3 but the loops run for 4 elements and you also update [3][3]
Basically your indexes overflow and you overwrite a different cell in the matrix.
Update: cheecked your input, use: int arey[4][4];
Arrays use 0 based indices, so the valid range of indices for your
int arey[3][3];
are 0 <= i < 3 and 0 <= j < 3
So you need to change the condition in your for loops to be strictly < instead of <=
I really don't think I understand your question, but this is wrong:
int arey[3][3];
...
for(j=0;j<=3;j++) // <= invalid
...
array[3][3]=1; // out of bounds
arey is a 3*3 array. You can't access arey[3][?], that's out of bounds. The only valid indices are 0..2.
Once you've written past the bounds of your array, your program behavior becomes undefined.