I have a class project to build an icebreaker game. The project is done is pieces, at the moment three functions need to be implemented: create display and getLocation. When I get to cin there is a runtime error SIGSEGV. The error only occurs if I have a cin after create. I've used cin.clear as well as cin.ignore in every position i can imagine. The only other problem I can get from google seems to be accesses out of memory range. To address this I've put the cin to a temp int as well as changed the function to get only a single int not of an array (cin>>location instead of cin>>location[0], with corresponding changes throughout the code). Nothing has had any effect. Further, if I strip the components out and build them individually they work fine on their own. I would greatly appreaciate advice, thanks.
#include <iostream>
#include <cstdlib>
#include <cstring>
usingnamespace std;
//prototypes
constint rows = 6; //to increase board size change increase rows and columns
constint columns = 8;
constint TILE = 4;
constchar playerA[TILE] = "[A]";
constchar playerB[TILE] = "[B]";
constchar ice[TILE] = "[#]";
constchar water[TILE] = "[ ]";
typedefchar Tile[TILE];
typedefint Player;
typedefstruct{
Tile tile;
}iceBoard;
iceBoard board[rows][columns];
Player player;
void iceCreate(iceBoard board[][columns]); //creates the game board
//pre: none
//post: a board is created with all tiles set to ice
bool isIce(iceBoard board[][columns]); //checks if a tile is ice
//pre: there is a board
//post: return true if the tile is ice. if tile is occupied or punched out false is returned.
bool icePunch(iceBoard board[][columns], Player player); //moves a player while punching put ice
//pre: game is in play and player can move to target
//post: if player can move player is put in target tile, old tile is set to water. Otherwise, returns false
bool iceCondition(iceBoard board[][columns], Player player); //checks if player is blocked in
//pre: game is in play
//post: if movement is possible (not surrounded by water/player) returns true, otherwise returns false.
void iceTurn(Player &player); //changes whose turn it is
//pre: a player has had a turn
//post: player is switched
void iceDisplay(iceBoard board[][columns]); //displays board
//pre: a board has been made
//post: the board is printed to the screen
void enterLocation(int location[]);
int main ()
{
int location[2];
iceCreate(board);
iceDisplay(board);
enterLocation(location);
return 0;
}
void iceCreate(iceBoard board[][columns]){
int i,j;
for(j=0;j<=rows; j++)
for (i=0;i<=columns; i++)
strcpy(board[i][j].tile,ice);
}
void iceDisplay(iceBoard board[][columns]){
int i,j;
for(j=0;j<=rows; j++){
cout<<endl;
for (i=0;i<=columns; i++)
cout<<board[i][j].tile;
}
}
void enterLocation(int location[]){
do{
cout<<"choose choose a row between 1 and "<<rows<<": ";
cin>>location[0];
cout<<endl;
location[0]--;
}while(location[0]<1||location[0]>7);
do{
cout<<"choose choose a column between 1 and "<<columns<<": ";
cin>>location[1];
cout<<endl;
location[1]--;
}while(location[1]<1||location[1]>9);
}
Is there a specific reason you are using arrays instead of vectors? Would greatly simplify your code if you used STL containers. E.g. you could return a std::pair for your enterLocation, you wouldn't even have to pass an array to it in the first place.
Its for cmpt 103 and we haven't covered vectors. Ive asked about leaving the scope of the class before but the prof wants us to use what we are given so we can learn it first.
Yeah right, skip STL at first because repeatedly running into the - for a beginner inevitable - seg faults is of course greatly improving the learning effect *sigh* I keep wondering why so many profs do that. I mean, you are not really programming C++ at the moment. This is "better C" not C++.
Anyways, to your problem(s): What compiler are you using? I can't see any faults, MSVC++ can't either, and at debugging time everything seems to behave as it should. (Though you should really think about creating something like a Location struct that you can return instead of taking an array as input parameter for your enterLocation function). I don't get any seg faults there, and in fact I can't see why you should get any at that point.
I'm using code blocks, its done fine until now. Ill have to try another ide. Ill create a struct for location and see what happens. By the way, thanks for the quick replies, I'm off to work soon so I'll post what happens tonight.
Edit: Nope still a seg error with the struct. New IDE tonight.
Funny, when compiling this with MinGW I also get seg faults. Maybe a bug with g++? Really, the only thing I could think of is that some code before this somehow breaks cin... though I don't really know what that could be. I hope someone answers this, cause right now I am quite stumped myself. I am pretty sure there is no error in this code, however normally MinGW doesn't have any troubles with cin...
EDIT: You must be doing something very funky with that one. It completely breaks my cin...
Wait a minute. What the heck does that code do? After running it, not even this works properly anymore:
I think it's important to learn the basic tools of the language first and well - even if an STL container would be a better tool for the job at hand. It's an exercise.
It looks like you are exceeding array bounds in your iceDisplay() and iceCreate(). Use < not <= in the for loops.
Your typedefs make understanding your code too difficult for me to see any other problems.
What does this:
1 2 3
typedefstruct{
Tile tile;
}iceBoard;
even mean?
Where is the location variable declared? It must be an int (or maybe Player) array. It must be there if the build succeeds but I was hoping to verify that it has at least 2 elements.
Sorry for double post but- I kinda freaked out here. I found your errors, and they are actually quite simple ones too:
First: All <= should be <. Everything else will result in a index out of bounds exception, and thus in an explosion - normally, if you are lucky. In this case apparently it doesn't, which is worse as we just saw.
your board[i][j] 's should be board[j][i] - you mixed up the way you name index variables by convention, and thus again tried to access illegal memory. Apparently this doesn't let your program explode, but in this case it seems to break the default input/output streams, which is why your program crashes at the next cin (at least I think that's the reason). Anyways, do what I just told you and your program will work again.
fun2code:
iceBorad lets me set up a table of arrays. ie. iceBoard board lets me have board[j][i].tile = ice. which looks like [#], or i can have board[j][i].tile = water, which gives me a [ ]. Simply it lets me set up a 2d array of tiles.
Edit: location is declared as int location[2] in the code above. it has been changed to a struct though. Also thank you for pointing out the out of bounds error.
Hanst99:
Thank you so much, im at work but Ill get that changed as soon as i get home.