C ++控制台程序(经常)不起作用,进程返回255(0xFF)

时间:2014-05-24 10:21:29

标签: c++ console console-application

我用一些树制作了简单的2D世界发生器。不幸的是,它并不总是奏效。有代码:

#include <assert.h>
#include <iostream>
#include <time.h>
#include <windows.h>
#include <conio.h>
#include <cstdlib>

using namespace std;

int main()
{
    string a[64][16];
    int lvl=10, num;

    srand(time(NULL));

for (;;)
{
    lvl=10;

    //! system("cls");
    for (int i=0; i<16; i++)
    {
        for (int j=0; j<64; j++)
        {
            a[j][i] = " ";
        }
    }


    for (int j=0; j<64; j++)
    {
        num = rand() % 10 + 1;
        cout << num;

        if (num == 1)
        {
            if (lvl > 7)
            {
                lvl--;
            }
        }
        else if (num == 2)
        {
            if (lvl < 15)
            {
                lvl++;
            }
        }
        a[j][lvl] = "O";

        num = rand() % 20 + 1;

        if (num == 7)
        {
            assert( lvl >= 6 );
            a[j][lvl-6] = "^";
            a[j-1][lvl-5] = "/";
            a[j+1][lvl-5] = "\\";
            a[j][lvl-5] = "|";
            a[j-1][lvl-4] = "/";
            a[j+1][lvl-4] = "\\";
            a[j][lvl-4] = "|";
            a[j-1][lvl-3] = "/";
            a[j+1][lvl-3] = "\\";
            a[j][lvl-3] = "|";
            a[j][lvl-2] = "|";
            a[j][lvl-1] = "|";

        }
    }
    cout << endl;

    cout << endl << " +------------------------------------------------------------    ----+" << endl;
    for (int i=0; i<16; i++)
    {
        cout << " |";
        for (int j=0; j<64; j++)
        {
            cout << a[j][i];
        }
        cout << "|" << endl;
    }
    cout << " +----------------------------------------------------------------+"     << endl;
    //! getch();
}
return 0;

} 有时它可以工作,有时只返回255(0xFF),有时返回随机代码(我认为),我不知道为什么会发生。

Debuger信息:

Starting debugger:
done
Registered new type: wxString
Registered new type: STL String
Registered new type: STL Vector
Setting breakpoints
Debugger name and version: GNU gdb 6.8
Child process PID: 6244
Program received signal SIGSEGV, Segmentation fault.
In std::string::assign () ()
At E:\C++\worldGenerator\main.cpp:59

3 个答案:

答案 0 :(得分:0)

以下是我检查您的计划所做的事情:

  • 添加了<assert.h>
  • 的附加内容
  • 清除屏幕并等待按键,使其成为非交互式。
  • 添加了assert关于lvl的预期值的声明。

然后,是的,它崩溃了。所以价值是不好的。您现在可以前往调试您的逻辑。


哦,我忍不住通过众所周知的盯着它的方法调试它

因为我看不到lvl可能变为6或更少的任何普通方式,所有更新都受条件限制。

但实际上,当j-1为0时,您使用j为数组建立索引。这会写入内存的某些意外部分。

许多C ++实现都有检查索引的方法。如果没有,那么您始终可以使用std::vector及其at成员函数。它提供有保证的范围检查。

无论如何,这是我推荐的,基于单个std::vector创建一个正确的矩阵类作为存储,并使用其at方法。


检测代码:

#include <assert.h>
#include <iostream>
#include <time.h>
#include <windows.h>
#include <conio.h>
#include <cstdlib>

using namespace std;

int main()
{
    string a[64][16];
    int lvl=10, num;

    srand(time(NULL));

    for (;;)
    {
        lvl=10;

        //! system("cls");
        for (int i=0; i<16; i++)
        {
            for (int j=0; j<64; j++)
            {
                a[j][i] = " ";
            }
        }


        for (int j=0; j<64; j++)
        {
            num = rand() % 10 + 1;
            cout << num;

            if (num == 1)
            {
                if (lvl > 7)
                {
                    lvl--;
                }
            }
            else if (num == 2)
            {
                if (lvl < 15)
                {
                    lvl++;
                }
            }
            a[j][lvl] = "O";

            num = rand() % 20 + 1;

            if (num == 7)
            {
                assert( lvl >= 6 );
                a[j][lvl-6] = "^";
                a[j-1][lvl-5] = "/";
                a[j+1][lvl-5] = "\\";
                a[j][lvl-5] = "|";
                a[j-1][lvl-4] = "/";
                a[j+1][lvl-4] = "\\";
                a[j][lvl-4] = "|";
                a[j-1][lvl-3] = "/";
                a[j+1][lvl-3] = "\\";
                a[j][lvl-3] = "|";
                a[j][lvl-2] = "|";
                a[j][lvl-1] = "|";

            }
        }
        cout << endl;

        cout << endl << " +------------------------------------------------------------    ----+" << endl;
        for (int i=0; i<16; i++)
        {
            cout << " |";
            for (int j=0; j<64; j++)
            {
                cout << a[j][i];
            }
            cout << "|" << endl;
        }
        cout << " +----------------------------------------------------------------+"     << endl;
        //! getch();
    }
    return 0;
}

答案 1 :(得分:0)

在VC ++ 2013中(在添加缺少的头之后),调试器在您在GDB中找到的std :: string :: assign()中引发异常。回滚调用堆栈表明这发生在以下行:

             a[j - 1][lvl - 5] = "/";

我修改后的代码中包含60行。此时j == 0,您的问题就在那里 - 索引a[-1]

通过设置srand(0)使测试可重复,它在其他地方失败:

             a[j + 1][lvl - 4] = "\\";

j == 64时。您的问题是循环将j从0迭代到63,因此j-1j+1可能超出范围,不应该用于索引a[]

    for( int j = 1; j < 63; j++ )

允许它至少运行 - 但可能会或可能不会按预期执行。

答案 2 :(得分:0)

我花了一段时间,但我明白了。 string a[64][16];太小,因为稍后你会这样做:

a[j+1][lvl-5] = "\\";,j最多为64,因此我将其更改为:string a[65][16];

我还发现如果你在9,10或11级生成一个树,程序也会崩溃,所以我在树生成中添加了一个限制。

这是固定代码:

#include <assert.h>
#include <iostream>
#include <time.h>
#include <windows.h>
#include <conio.h>
#include <cstdlib>

using namespace std;

int main()
{
    string a[65][16];
    int lvl=10, num;

    srand(time(NULL));

for (;;)
{
    lvl=10;

    system("cls");
    for (int i=0; i<16; i++)
    {
        for (int j=0; j<64; j++)
        {
            a[j][i] = " ";
        }
    }


    for (int j=0; j<64; j++)
    {
        num = rand() % 10 + 1;
        cout << num;

        if (num == 1)
        {
            if (lvl > 7)
            {
                lvl--;
            }
        }
        else if (num == 2)
        {
            if (lvl < 15)
            {
                lvl++;
            }
        }
        a[j][lvl] = "O";

        num = rand() % 20 + 1;

        if (num == 7 && (lvl < 9 || lvl > 11))
        {
            assert( lvl >= 6 );
            a[j][lvl-6] = "^";
            a[j-1][lvl-5] = "/";
            a[j+1][lvl-5] = "\\";
            a[j][lvl-5] = "|";
            a[j-1][lvl-4] = "/";
            a[j+1][lvl-4] = "\\";
            a[j][lvl-4] = "|";
            a[j-1][lvl-3] = "/";
            a[j+1][lvl-3] = "\\";
            a[j][lvl-3] = "|";
            a[j][lvl-2] = "|";
            a[j][lvl-1] = "|";

        }
    }
    cout << endl;

    cout << endl << " +----------------------------------------------------------------+" << endl;
    for (int i=0; i<16; i++)
    {
        cout << " |";
        for (int j=0; j<64; j++)
        {
            cout << a[j][i];
        }
        cout << "|" << endl;
    }
    cout << " +----------------------------------------------------------------+"     << endl;
    getch();
}
return 0;
}