0

我正在为游戏 Flood-It(我认为也称为 Blobs)制作求解器。该程序编译并运行良好,直到最后。. . 我在 main() 函数的末尾做了一个最终的“cout”(然后添加了“return 0”,没有任何效果),它弹出“FloodItSolver.exe 已停止工作......”

当我执行“gdb FloodItSolver”然后执行“r”时,我以以下输出结束:

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

关于“未完成”的那部分是我最后想到的。

更新:这是在 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)

这是没有意义的,因为我的 main() 结束了!为什么会在这里出现SegFault?

我的代码:

#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;
}
4

3 回答 3

3

在这段代码中:

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);
}

您不检查是否find返回npos。因此,您将对string对象进行螺旋索引。

此外,在Pivot

//...
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<14)
{
    if((grid[x][y+1]==grid[x][y])&&(isFlood[x][y+1]==false))
    {
        isFlood[x][y+1]=true;
        Pivot(x, y+1);
    }
}

您正在索引超出isFlood数组的边界并为其分配一个值。

于 2012-07-26T15:58:10.313 回答
3

完成后的错误表明存在静态存储持续时间main中的变量或对象的破坏问题。main如果您从调试器打印回溯,您至少会看到发生错误时被销毁的对象的类型。

于 2012-07-26T15:52:10.633 回答
0

尝试使用http://en.wikipedia.org/wiki/Valgrind构建

于 2012-07-26T15:56:55.837 回答