Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
The community is reviewing whether to reopen this question as of 1 year ago.
Improve this question
So i have written the following method in a class:
Array & operator = (const Array &a) {
/*delete [] array;
priv_size = a.priv_size; HOW DOES THIS EVEN DO SOMETHING???
priv_base = a.priv_base;
array = new int[priv_size*priv_size];
for (int i=0; i<priv_size*priv_size; i++)
array[i] = a.array[i];
return *this;
*/
}
as you can clearly see it is all in one big comment. However, when i call the = operator in main like this:
cout << a; //there is an operator << too
cout << endl;
Array b = a;
b[1][1] = 39;
b[3][1] = 2;
cout << b;
cout << endl;
cout << a;
where a is the following array:
0 0 0 0
0 0 0 0
3 0 0 0
0 0 0 5
this happens:
0 0 0 0
0 0 0 0
3 0 0 0
0 0 0 5
0 0 0 0
0 39 0 0
3 0 0 0
0 2 0 5
0 0 0 0
0 0 0 0
3 0 0 0
0 0 0 5
As you can see i also change some values in b, but a remains intact which means b is not by mistake somehow connected to a in any way.
What is going on here? Help.
Thanks.
EDIT: I moved the comment so that it covers the whole method including the Array & operator = (const Array &a) part. The exact same thing happens(????). How is this possible? It almost seems like there is already a default operator = method, which does't really make too much sense, because why would c++ prioritize such a method, and even if it does, why set it so that it copies a whole array?.
Also, here is the constructor, since a lot of people needed to see it:
Array (int s = 0, int b = 0) :
array(new int[s*s]), priv_size(s), priv_base(b) {
for (int i=0; i<priv_size*priv_size; i++)
array[i] = 0; //sets everything to 0
}
My question is answered:
In my example i wrote Array b = a;, which in c++ calls the copy constructor and not the opperator =
This is documented here:
https://en.cppreference.com/w/cpp/language/copy_initialization
As well as here:
https://en.cppreference.com/w/cpp/language/copy_constructor
Thanks to everyone who took the time to read the question and comment.
Related
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.
This question already has answers here:
What happens to a declared, uninitialized variable in C? Does it have a value?
(9 answers)
Closed 7 years ago.
EDIT: ^^^ "duplicate" doesn't mention arrays at all
EDIT2: Hold on that's in C, not C++, isn't there a difference between 2 languages ?!
This question has been bugging me for some time lately. Google search revealed nothing.
So I have this snippet of example C++ code:
int factors[100]; /* note this is not initialized */
int number = /* less than 100 */ 10;
for (int i = 0; i < number; i ++) {
factors[i] = 1;
}
for (int i = 0; i < 100; i ++) {
std::cout << factors[i] << std::endl;
}
The output is (scroll down to bottom)
1
1
1
1
1
1
1
1
1
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1640775680
32767
114023525
624860211
174064279
236792104
-1027703263
587262357
1599638600
32767
17
0
1
0
6778984
1
1640935824
32767
1599638352
32767
1640780406
32767
1599638384
32767
1599638384
32767
1
0
1599638408
32767
6778880
1
1640776264
32767
1599638424
32767
0
0
0
0
0
0
0
0
0
0
Why isn't it either ten 1s or ten 1s and ninety 0s, and why are there so many seemingly random (maybe related to powers of 2?) numbers? I think it may have something to do with memory allocation or something but I'm just a beginner and I've not gotten into this stuff yet.
If you have the declaration
int factors[100]; /* note this is not initialized */
there are two situations:
When declared as a global (file scope) variable, the entire array will be initialised to zeros before your program starts.
When declared as a local (function scope) variable, the array is not initialised and will contain unpredictable numbers.
The uninitialized arrays are filled with garbage values.Garbage values are those values present in that specific memory location before the user requests for it.The memory location have always existed.In many cases the output is 0 as compiler explicitly writes defualt values before returning these locations.But this behaviour is not always exhibited by C/C++ compilers,hence the presence of a varied output.
Thats just the thing, if you don't initialize your arrays, C++ does not guarantee it will be blank
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I am trying to recreate the game 2048 in C++.
I'm working on a spawn function right now. It takes in an array of the current values of the 16 spots, randomly scans for an empty one, and puts either a 2 or a 4 in that spot.
I am starting out with a test array, b. I want to pass this array to a function that will alter one of its values, which I know I need to do by passing a pointer, but none of the changes are staying after I leave the function.
Can anyone see what is wrong here? How do I properly pass the array in so the changes will stay after the spawn function?
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
void showBoard(int board[]);
void spawn(int* board);
int main() {
srand(time(NULL));
int b[16] = {2, 2, 2, 2};
int* bp = b;
showBoard(b);
spawn(bp);
showBoard(b);
}
// print out the 16 current tiles to the console
void showBoard(int board[]) {
for(int i=0; i<=15; ++i){
if(i%4==0)
cout<<'\n';
cout<<board[i]<<" ";
}
cout<<'\n';
}
void spawn(int* board) {
int x; // index
// randomly choose an index to spawn a 2 or 4:
do x=rand()%16; while(board[x]!=0);
// when found empty place (with value 0), spawn a new tile.
/* there should be a 90% chance of spawning a 2
* and a 10% chance of spawning a 4. Generate a
* random number between 0 and 9, and if it is
* 9, make the new spawn tile a 4.
*/
if (rand()%10 == 9) {
board[x] == 4;
cout << "added 4 \n";
}
else {
board[x] == 2;
cout << "added 2 \n";
}
}
The output:
2 2 2 2
0 0 0 0
0 0 0 0
0 0 0 0
added 2
2 2 2 2
0 0 0 0
0 0 0 0
0 0 0 0
So my cout confirms that I got to the if block where I would set board[x] to 2, but when I do showBoard afterwards, there is no update to the array. Any help?
board[x] == 2;
board[x] == 4;
Need to be:
board[x] = 2;
board[x] = 4;
Also, it may make the code simpler if you make this a 2D 4x4 array. Picking a random square would then become:
int x = rand() % 16;
int board_spot = board[x%4][x/4];
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I'm new to c++ and i'm trying to read in a file and store it in a 9x9 array, can anyone explain how i can do this whilst keeping it as simple as possible?
The aim is too make a Sudoku solver.
File looks like;
0 3 0 0 0 1 0 7 0
6 0 0 8 0 0 0 0 2
0 0 1 0 4 0 5 0 0
0 7 0 0 0 2 0 4 0
2 0 0 0 9 0 0 0 6
0 4 0 3 0 0 0 1 0
0 0 5 0 3 0 4 0 0
1 0 0 0 0 6 0 0 5
0 2 0 1 0 0 0 3 0
Thanks in advance.
You need to use std::istringstream
For example
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
//...
const size_t N = 9;
int a[N][N] = {};
std::ifstream file( "SomeFileName" );
std::string line;
for ( size_t i = 0; i < N && std::getline( file, line ); i++ )
{
std::istringstream is( line );
size_t j = 0;
while ( j < N && is >> a[i][j] ) j++;
}
If you should not bother that a line can contain more or less than 9 numbers per line then you can write simply
#include <iostream>
#include <fstream>
//...
const size_t N = 9;
int a[N][N] = {};
std::ifstream file( "SomeFileName" );
size_t i = 0;
while ( i < N * N && file >> a[i / N ][i % N] ) i++;
There are several ways you could do this, all of which start with opening the file first though. To do this, you will need to include fstream and create a "file in" reader (look at the ifstream class).
Once you have that it's pretty straight forward. You can either grab character by character by just looping to the end of the file and storing the number accordingly OR you can grab the file line by line and then loop through each line to grab the numbers. If you do the later, there are methods that will help split the string into an array based on the spaces but I'll let you look that up. Also, getting the line will mean you will need to catch the newline character into a junk variable so it can continue on, else the next time you get a line it will just get that variable anyways.
for and while loops are going to be your friend in this.
Also, don't forget to close your file stream when you're done too.
EDIT:
I forgot to mention that if you do the line by line way, you will need to use some method to turn a string/array into an integer (atoi is one, i also think there is a stoi but you may need to include string to use that or I'm mistaken about that one). Doing it character by character you can go straight into an integer, but you better make sure there isn't any non-number character in your file and that there won't be.
So I'm working on the life game, and so far I have come up with this http://ideone.com/QG4tsS I'm not sure exactly if I am on the right track or not. Basically I have a function putting out random values to try and test my code. But nothing seems to happen. I suspect my problem lies with the following code
int sum = 0;
for (int k = (i - 1); k <= (i + 1); k++) {
for (int l = (j - 1); l <= (j + 1); l++) {
sum += currentGen[k][l];
}
}
return sum;
So my result gives me a 2d array with all 0's but shouldn't I start to see some changes and patterns starting to form? I get one 1 and the rest are 0.
Output
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 1
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
I provide this answer based on the code you posted at http://ideone.com/QG4tsS . You really should consider adding that code to your original question, so that future folks who find this on StackOverflow have the full context.
Your RandomCells function only sets cells to 1 if they meet the RANDOM threshold. It doesn't clear them to 0 otherwise. Once you fix that, you'll be all set. ie.
void RandomCells(int currentGen[][CELLY]) {
for (int i = 0; i < CELLX; i++) {
for (int j = 0; j < CELLY; j++) {
if (rand() % 100 + 1 < RANDOM) {
currentGen[i][j] = 1;
} else
{
currentGen[i][j] = 0;
}
}
}
}
Without that else clause, I was seeing initial generations that looked like this:
0 0 4196155 1
1813657216 1 4197653 0
-870503576 1 4197584 1
Clearly, most of those cells were non-zero, and so Conway's Life algorithm would map them to 0 in the next generation because of "crowding".
The reason currentGen was filled with such 'random' values is that it was allocated as an automatic variable to main. Automatic variables do not get initialized to any particular value. You need to initialize them yourself. You can do that by modifying your algorithm (as I did above), or by adding an explicit bit of code to initialize the structure.
This differs from file-scope variables, which C and C++ define as initialized-to-zero on program start if they don't have initializers or default constructors. (Pedants will point out that even that has caveats.)
Once you make the required fixes, to truly see Conway's Life, you'll need to set CELLX and CELLY to larger values...