I’m making a solver for the game Flood-It (I think also known as Blobs). The program compiles and runs fine until the very end . . . I do a final “cout” (and then added the “return 0” with no effect) at the end of my main() function, and it pops up “FloodItSolver.exe has stopped working…”
When I do a “gdb FloodItSolver” and then “r” I end with the following output:
Did not complete in 25 turns.
Program received signal SIGSEGV, Segmentation fault.
0x6fc5b222 in libstdc++-6!_ZN9__gnu_cxx18__exchange_and_addEPVii () from C:\MinGW\bin\libstdc++-6.dll
That part about “Did not complete” is the last thing I cout.
UPDATE: Here is the result of issuing the “backtrace” command at gdb:
(gdb) backtrace
#0 0x6fc5b222 in libstdc++-6!_ZN9__gnu_cxx18__exchange_and_addEPVii () from C:\MinGW\bin\libstdc++-6.dll
#1 0x6fcbd66e in libstdc++-6!atomic_flag_test_and_set_explicit () from C:\MinGW\bin\libstdc++-6.dll
#2 0x00401fee in __tcf_2 () at flooditsolver.cpp:9
#3 0x75b3c3e9 in msvcrt!isspace () from C:\Windows\syswow64\msvcrt.dll
#4 0x75b437df in msvcrt!_cexit () from C:\Windows\syswow64\msvcrt.dll
#5 0x00000000 in ?? ()
(gdb)
It makes no sense because I hit the end of my main()! Why would it SegFault here?
My code:
#include <iostream>
#include <fstream>
using namespace std;
// GLOBAL---------------------------------------------------------------------
int rgbPos, scPos, color, grid[14][14];
ifstream file("Floodit.txt");
bool isFlood[14][14];
string line;
// END GLOBAL-------------------------------------------------------------
// Function Pool ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
// HighestBorderCount(), NonFloodColorsLeft(), CanEliminateAColor(), etc...
// Gather a list of variables you consider when planning your next move, then make a function for it
// So far I only have HighestBorderCount()
int HighestBorderCount()
{
int highest=0, returnMe, countColors[6]={0,0,0,0,0,0};
bool paddedBorder[16][16], border[14][14];
for(int x=0;x<16;x++) {for(int y=0;y<16;y++) {paddedBorder[x][y]=false;}}
for(int x=0;x<14;x++) {for(int y=0;y<14;y++) {border[x][y]=false;paddedBorder[x+1][y+1]=isFlood[x][y];}} // Create copy of isFlood, zero out border[][]
for(int x=0;x<14;x++)
{
for (int y=0;y<14;y++)
{
if( (!paddedBorder[x+1][y+1]) && ( (paddedBorder[x][y+1]) || (paddedBorder[x+1][y]) || (paddedBorder[x+2][y+1]) || (paddedBorder[x+1][y+2]) ) ) border[x][y]=true;
if(border[x][y])
{
switch(grid[x][y])
{
case 0:
countColors[0]++;
cout<<"0 on border\n";
break;
case 1:
countColors[1]++;
cout<<"1 on border\n";
break;
case 2:
countColors[2]++;
cout<<"2 on border\n";
break;
case 3:
countColors[3]++;
cout<<"3 on border\n";
break;
case 4:
countColors[4]++;
cout<<"4 on border\n";
break;
case 5:
countColors[5]++;
cout<<"5 on border\n";
break;
}
}
}
}
for(int x=0;x<6;x++) if(countColors[x]>highest) highest=countColors[x];
for(int x=0;x<6;x++) if(countColors[x]==highest) returnMe=x;
return returnMe;
}
// End Function Pool ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
void Pivot(int x, int y)
{
if(x>0)
{
if((grid[x-1][y]==grid[x][y])&&(isFlood[x-1][y]==false))
{
isFlood[x-1][y]=true;
Pivot(x-1, y);
}
}
if(x<14)
{
if((grid[x+1][y]==grid[x][y])&&(isFlood[x+1][y]==false))
{
isFlood[x+1][y]=true;
Pivot(x+1, y);
}
}
if(y>0)
{
if((grid[x][y-1]==grid[x][y])&&(isFlood[x][y-1]==false))
{
isFlood[x][y-1]=true;
Pivot(x, y-1);
}
}
if(y<14)
{
if((grid[x][y+1]==grid[x][y])&&(isFlood[x][y+1]==false))
{
isFlood[x][y+1]=true;
Pivot(x, y+1);
}
}
}
void Flood(int FloodColor)
{
for(int x=0;x<14;x++) {for (int y=0;y<14;y++) {if (isFlood[x][y]) Pivot(x,y);}} // This run tells us what area to include in the flood
for(int x=0;x<14;x++)
{
for(int y=0;y<14;y++)
{
if(isFlood[x][y]) grid[x][y]=FloodColor; // This floods the area
cout<<grid[x][y]<<" ";
}
cout<<endl;
}
cout<<endl;
for(int x=0;x<14;x++) {for (int y=0;y<14;y++) {if (isFlood[x][y]) Pivot(x,y);}} // This updates the flood area, so we include newly acquired blocks
}
int GetColor(string s)
{
s=s.substr(0,s.find(","));
if(s=="237") return 0; // PINK == 0
else if(s=="96") return 1; // PURPLE == 1
else if(s=="243") return 2; // YELLOW == 2
else if(s=="220") return 3; // RED == 3
else if(s=="70") return 4; // BLUE == 4
else if(s=="126") return 5; // GREEN == 5
else return 6;
}
int main(/*int argc, char* argv[]*/)
{
int input, counter=0;
for(int x=0;x<14;x++) {for(int y=0;y<14;y++) {isFlood[x][y]=false;}}
isFlood[0][0]=true;
// GET INPUT
if(file.is_open()) {while(file.good()) {getline(file, line);}}
file.close();
// POPULATE GRID
line=line.substr(11);
for(int x=0;x<196;x++)
{
rgbPos=line.find("rgb");
scPos=line.find("; \">");
color=GetColor(line.substr(rgbPos+4,scPos-1-(rgbPos+4)));
grid[x/14][x%14]=color;
line=line.substr(scPos+3);
}
bool complete=false;
bool floodCheck;
while((!complete)&&(counter<25))
{
counter++;
floodCheck=true;
//cout<<"Highest border count: "<<HighestBorderCount()<<endl;
//cin>>input;
Flood(HighestBorderCount());
for(int y=0;y<14;y++) {for(int z=0;z<14;z++) {if(!isFlood[y][z]) floodCheck=false;}}
if(floodCheck) complete=true;
}
if(complete) {cout<<"Completed in "<<counter<<" turns!";} else {cout<<"Did not complete in 25 turns.";}
return 0;
}
An error after
maincompletes indicates an issue with destruction of the variables inmainor objects with static storage duration. If you print the backtrace from the debugger you will at least see the type of the object being destroyed when the error occurred.