我用一些树制作了简单的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
答案 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-1
和j+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;
}