iostream changes a pointer

I'm writing a chess program, and once I use any cout or cin or cerr, a pointer in board[8][8] changes, and becomes a null pointer.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
	
int main()        
{
//initialization of board, which is a global 2-dimensional array of pointers to piece objects
        cout << "Is this program going to be white(1) or black(0)?" << endl;
	cin >> imwhite; //global boolean
	if(imwhite==true)
	{
		board[1][4]->move(4,3);
		cout << "Enter the coordinates of where you moved from (x\\ny) 
and where you are going(x\\ny)" << endl;
		int ox=0;
		int oy=0;
		int nx=0;
		int ny=0;
		cin >> ox;
		cin >> oy;
		cin >> nx;
		cin >> ny;
        }
        return 0;
}
int move(int newx, int newy)
{
	board[newy][newx]=&pawn(piece(newx, newy, 1, white));
	board[y][x]=&piece();
	return 0;
}


piece has several virtual functions, including move. This is the move function of the pawn class, which inherits piece. y and x are member variables of piece.

I ran this in debug mode, and at line 10/11, once I print to the console, the pointers in board[1][4] and board[3][4], the ones changed by move(), are null pointers. I experimented and changed from line 10 to be a cin, and a cerr, and both make the pointers null. If I don't use anything from iostream, just initialize the variables, and do whatever, the pointers are normal. Anything I can do to stop the pointers from becoming null pointers?
Thanks for reading :)

how board is defined?

what are you trying to do here:
board[y][x]=&piece();
board is defined as:
piece *board[8][8];

board[y][x]=&piece(); is meant to set the square from which I moved, in this case 1,4, to be a blank square, and piece has a default constructor.
Note: after a bit more debugging, I found that memory that a pointer in board that was modified by move() is made useless or overwritten with trash any time a function is called, the moment it is called. I think it could be because I set the pointer to point at a temporary variable.
1
2
  board[newy][newx]=&pawn(piece(newx, newy, 1, white));
	board[y][x]=&piece();

Since its temporary, its memory address can be overwritten.
Am I right, and if yes, how do I prevent the memory address from being overwritten?
There are couple of things which came, use of three dimensional pointer which is unnecessary here. move is creating temporaries which can cause problem.

Rest, without seeing the whole code it becomes difficult to point at the correct problem. Specially in case of pointers the culprit is not necessarily near where the problem is. It could be in other corner of the code too.
No other code is being executed, except this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
        board[1][0]=&pawn(piece(0,1,1,true));
	board[1][1]=&pawn(piece(1,1,1,true));
	board[1][2]=&pawn(piece(2,1,1,true));
	board[1][3]=&pawn(piece(3,1,1,true));
	board[1][4]=&pawn(piece(4,1,1,true));
	board[1][5]=&pawn(piece(5,1,1,true));
	board[1][6]=&pawn(piece(6,1,1,true));
	board[1][7]=&pawn(piece(7,1,1,true));
	board[0][0]=&rook(piece(0,0,5,true));
	board[0][1]=&knight(piece(1,0,3,true));
	board[0][2]=&bishop(piece(2,0,3,true));
	board[0][3]=&queen(piece(3,0,9,true));
	board[0][4]=&king(piece(4,0,100,true));
	board[0][5]=&bishop(piece(5,0,3,true));
	board[0][6]=&knight(piece(6,0,3,true));
	board[0][7]=&rook(piece(7,0,5,true));

	board[6][0]=&pawn(piece(0,6,1,false));
	board[6][1]=&pawn(piece(1,6,1,false));
	board[6][2]=&pawn(piece(2,6,1,false));
	board[6][3]=&pawn(piece(3,6,1,false));
	board[6][4]=&pawn(piece(4,6,1,false));
	board[6][5]=&pawn(piece(5,6,1,false));
	board[6][6]=&pawn(piece(6,6,1,false));
	board[6][7]=&pawn(piece(7,6,1,false));
	board[7][0]=&rook(piece(0,7,5,false));
	board[7][1]=&knight(piece(1,7,3,false));
	board[7][2]=&bishop(piece(2,7,3,false));
	board[7][3]=&queen(piece(3,7,9,false));
	board[7][4]=&king(piece(4,7,100,false));
	board[7][5]=&bishop(piece(5,7,3,false));
	board[7][6]=&knight(piece(6,7,3,false));
	board[7][7]=&rook(piece(7,7,5,false));
	for(int i=2; i<6; i++)
	{
		for(int j=0; j<8; j++)
		{
			board[i][j]=&piece();
		}
	}


which is at the top of main, where I had //initialization of board in my first post.
Also the constructors, which involve no pointers.

There are couple of things which came, use of three dimensional pointer which is unnecessary here.


What do you mean?

piece *board[8][8];

this makes it a three dimensional array. Instead i think it could have been like this:

piece board[8][8] or piece **board;
I am not sure, but I think that if it was piece board[8][8] then I can't set it to the piece part of, say, a pawn, or a rook, which inherit piece.

i.e. I can't do this board[1][0]=pawn(piece(0,1,1,true));

This will create a temporary object:

&pawn(piece(0,1,1,true));

which will not exist as soon you will exit a function. What do you think about this?

test this program:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
class board
{

private:
	int x;
	int y;

public:
	board()
	{
		x = 0;
		y = 0;
	}

	board(int a, int b)
	{
		x = a;
		y = b;
	}


public:
	void print()
	{
		std::cout << x << " " << y << std::endl;
	}

};


board *b[2][2];

void init()
{

	b[0][0] = &board(10, 10);
	b[1][1] = &board(20, 20);

}
int main()
{
	init();
	b[0][0]->print();
	b[1][1]->print();


	
	return 0;
} 



When init finishes, see the value of b and compare it with the values when the code was in init().
when you say,

int x[8][8], you get 8 * 8 slots. so total of 64 slots.

when you say int *x[8][8].

This means you got 64 slots and each slot can have infinite number of slots (the star you put in the beginning). So you don't want to do this. I think you only want 64 slots.

So now you have two options. Either make the objects on stack and set each propertywith a set method like this:

1
2
3
4
5
board b[8][8]; //default constructor will run
for each 64 slots
b[i][j].setx();
b[i][j].sety();
b[i][j].setcolor();



or

board **b;
for each pointer allocate memory using new board(0,1,1,true);

see how to allocate memory to double pointer's.

I ran the code with the board class, and after init() executed, the values were fine, but once print was called, they became trash, and only trash printed.

I do want 64 slots, but I want each slot to hold a pointer to an object, not an object.
I solved the problem: I store the temporary variable in an vector, which is global, so that it is permanent. Then I point to a part of that vector. This is messy though, since whenever I move, I push_back the vector, which changes the memory address of the vector, so I have to compensate. Although it is slow and inefficient, it will have to do. Thanks.
Last edited on
for your kind or problem, learn to use new/delete. Otherwise it will be messy to a point that you will not be able to move forward. Don't find workarounds. :)
happy programming.
Topic archived. No new replies allowed.