0

私はゲームFlood-It(Blobsとしても知られていると思います)のソルバーを作成しています。プログラムはコンパイルされ、最後まで正常に実行されます。。。main()関数の最後に最後の「cout」を実行し(その後、効果なしで「return 0」を追加)、「FloodItSolver.exeが動作を停止しました...」というポップアップが表示されます。

「gdbFloodItSolver」を実行してから「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で「backtrace」コマンドを発行した結果は次のとおりです。

(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

完了後のエラーは、静的ストレージ期間のオブジェクトまたはオブジェクトmainの破棄に問題があることを示しています。mainデバッガーからバックトレースを出力すると、少なくともエラーが発生したときに破棄されたオブジェクトのタイプがわかります。

于 2012-07-26T15:52:10.633 に答える
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 に答える
0

http://en.wikipedia.org/wiki/Valgrindでビルドしてみてください

于 2012-07-26T15:56:55.837 に答える