向我的小游戏添加功能时出现奇怪错误 (0xC0000005)
Strange error while adding a feature to my little game (0xC0000005)
大家好,
前段时间我决定编写自己的扫雷版本作为练习,我做到了。游戏 运行 完美,但在决定添加“选择难度”选项后 window 冻结,我收到一条错误消息,说程序没有响应。 0xC0000005 行也出现了。我已经尝试了很多很多事情:将代码从 main() 移动到一个单独的函数(现在全部在 int playGame() 中),分配一些堆中的更多内存,甚至创建一个单独的 .c 文件来存储一些代码,但到目前为止没有任何效果。几周后我回到了代码,但我仍然不知道为什么会这样。
谁能帮我这个?我希望我的代码不难读。我添加了一些评论来解释什么是什么。我还是C的新手
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "difLvl.c"
int displayFiled(char **field); //prints out the map of the field
int combine(char answer, int answer1); //combines user input and field numeration
int Randomizer(int **mineArray); //generates random mine map
int difficulty();
int playGame();
int main(){
int playGame();
playGame();
system("PAUSE");
return 0;
}
int Randomizer(int **mineArray){
int difficulty();
int i, j;
srand(time(NULL));
int mines;
int placeMine;
int totalMines;
//int difLvl=2;
int difLvl=difficulty();
for(i=0, totalMines=0; i<10; i++){
for(j=0, mines=0; j<10 && mines<difLvl; j++){
placeMine= rand() % 2;
mineArray[i][j] = placeMine;
if(placeMine==1){
++mines;
};
};
totalMines+=mines;
};
return totalMines;
}
int displayFiled(char **field){
int i, j;
printf(" A B C D E F G H I J\n");
printf(" --------------------\n");
for (i=0; i<10; i++){
if (i==9){
printf("%d |", i+1);
}else{
printf("%d |", i+1);
};
for (j=0; j<10; j++){
printf("%c ", field[i][j]);
if (j==9){
printf("\n");
};
};
};
printf("\n");
return 0;
}
int playGame(){
int displayFiled(char **field);
int combine(char answer, int answer1);
int Randomizer(int ** mineArray);
char Y_char; //column as character (a, b, c etc.)
int X; //row
int Y; //Y_char converted to a number
int **mineArray; //stores the map of mines
char **fieldDisplay; //prints out the map of the field
int i, j; //counters
int life=1;
int movePl=0; //no dying on the first move
int globalMines; //number of mines placed
int openedFields=0; //counts the number of fields opened
//int difLvl;
//int difficulty();
//difLvl= difficulty();
/*disabled the trhee lines above while I was trying some solutions*/
/*int difficulty() is now called from int Randomizer()*/
system("cls");
/*Allocates memory to mineArray*/
mineArray= (int*)calloc(10, sizeof(int));
for(i = 0; i < 10; i++){
mineArray[i] = calloc(10, sizeof(int));
};
/*Allocates memory to fieldDisplay*/
fieldDisplay= (int*)calloc(10, sizeof(int));
for(i = 0; i < 10; i++){
fieldDisplay[i] = calloc(10, sizeof(int));
};
/*default look of fields with ?*/
for (i=0; i<10; i++){
for (j=0; j<10; j++){
fieldDisplay[i][j]='?';
};
};
globalMines= Randomizer(mineArray);
while(life==1 && openedFields<(100-globalMines)){
/*for checking purposes only*/
/*for (i=0; i<10; i++){
for (j=0; j<10; j++){
printf("%d ", mineArray[i][j]);
if (j==9){
printf("\n");
};
};
};*/
//printf("\nDifficulty level %d\n", difLvl);
printf("Total number of mines is %d\n\n", globalMines);
printf("\tMove nr. %d\n\n", movePl+1);
displayFiled(fieldDisplay);
printf("Which field do You want to activate?\nType first the letter, space and then the number (A 1, B 10 etc.)\n");
scanf("%c %d", &Y_char, &X);
if (Y_char >= 'A' && Y_char <= 'Z'){
Y = Y_char - 'A';
}else if(Y_char >= 'a' && Y_char <= 'z'){
Y = Y_char - 'a';
};
/*checks if a field is a mine*/
/*X-1 because the player chooses from 1 to 10*/
if (mineArray[X-1][Y]==0 && fieldDisplay[X-1][Y]=='?'){
movePl++;
fieldDisplay[X-1][Y]='0';
openedFields=openedFields+1;
OPEN : if (((X-2)<10) && ((X-2)>=0)){
if (mineArray[X-2][Y]==0 && fieldDisplay[X-2][Y]=='?'){
fieldDisplay[X-2][Y]='0';
openedFields=openedFields+1;
};
};
if ((X<10) && (X>=0)){
if (mineArray[X][Y]==0 && fieldDisplay[X][Y]=='?'){
fieldDisplay[X][Y]='0';
openedFields=openedFields+1;
};
};
if (((Y+1)<10) && ((Y+1)>=0)){
if (mineArray[X-1][Y+1]==0 && fieldDisplay[X-1][Y+1]=='?'){
fieldDisplay[X-1][Y+1]='0';
openedFields=openedFields+1;
};
};
if (((Y-1)<10) && ((Y-1)>=0)){
if (mineArray[X-1][Y-1]==0 && fieldDisplay[X-1][Y-1]=='?'){
fieldDisplay[X-1][Y-1]='0';
openedFields=openedFields+1;
};
};
system("cls"); //clears console screen
}else if (mineArray[X-1][Y]==0 && fieldDisplay[X-1][Y]=='0'){
system("cls");
printf("You can't choose an already opened field!\n\n");
}else if(mineArray[X-1][Y]==1 && movePl==0){
/*only activates on the first turn if players hits mine*/
movePl++;
mineArray[X-1][Y]= 0;
fieldDisplay[X-1][Y]='0';
globalMines=globalMines-1;
goto OPEN;
system("cls");
}else{
system("cls");
printf("YOU DIED ! YOU DIED ! YOU DIED !\n\n");
printf("Moves successfully made: %d\n\n", movePl-1);
fieldDisplay[X-1][Y]='1';
displayFiled(fieldDisplay);
--life;
};
};
if(openedFields==(100-globalMines)){
printf("Congratulations! You won the game!\n\n");
displayFiled(fieldDisplay);
};
for(i = 0; i < 10; i++){
free(mineArray[i]);
};
free(mineArray);
for(i = 0; i < 10; i++){
free(fieldDisplay[i]);
};
free(fieldDisplay);
return 0;
}
difLvl.c 文件:
#include <stdio.h>
#include <stdlib.h>
int difficulty(){
int difLvl;
while(1){
printf("Please choose a difficulty level:\n");
printf("Easy-1\nNormal-2\nNightmare-3\n");
printf("Your answer: ");
scanf(" %d", &difLvl);
if(difLvl>=1 && difLvl<=3){
break;
}else{
system("cls");
continue;
};
};
system("cls");
return difLvl;
}
我创建了它,因为我认为也许 main() 中的代码太多,这也许就是难度选项无法正常工作的原因。
编辑
提示用户输入难度级别后,创建了矿山地图,但选择了一个文件后,程序崩溃了。
已解决
scanf("%c %d", &Y_char, &X);
变成
scanf(" %c %d", &Y_char, &X);
首先,你没有正确分配你的二维字段。 "outer" 字段必须包含 int *
,而不仅仅是 int
:
mineArray = calloc(10, sizeof(*mineArray));
for (i = 0; i < 10; i++) {
mineArray[i] = calloc(10, sizeof(*mineArray[i]));
}
分段错误的另一个潜在来源是 Y
可能最终未初始化,因此具有垃圾值。原因是 scanf
:
scanf("%c %d", &Y_char, &X);
大多数 scanf
格式在转换前跳过白色 space,但 %c
不会。当您希望阅读一个字母时,很可能您将换行符读作 %c
的字符。因为换行符是白色的 space,你可以通过在 %c
之前放置一个 space 来修复它?格式:
scanf(" %c %d", &Y_char, &X);
(我说热修复,因为它不是一个好的解决方案。scanf
不特别对待换行符;它们只是 space。更好的解决方案可能是首先用 fgets
读取一行,然后用 sscanf
扫描它。至少你可以把每一行都当作 frash 输入。(你的输入确实应该确保忽略错误的输入。)
最后,奇怪的是你包含了一个*.c
文件。如果你想将 ypur 项目分布在各种文件上,这基本上是个好主意,你应该为每个 *.c
编写一个头文件,它有文件的接口。在其他 *.c
个文件中包含头文件;分别将 *.c
个文件编译成对象,然后 link 它们。这个过程通常由 Makefiles 或 Projects 控制。
大家好,
前段时间我决定编写自己的扫雷版本作为练习,我做到了。游戏 运行 完美,但在决定添加“选择难度”选项后 window 冻结,我收到一条错误消息,说程序没有响应。 0xC0000005 行也出现了。我已经尝试了很多很多事情:将代码从 main() 移动到一个单独的函数(现在全部在 int playGame() 中),分配一些堆中的更多内存,甚至创建一个单独的 .c 文件来存储一些代码,但到目前为止没有任何效果。几周后我回到了代码,但我仍然不知道为什么会这样。 谁能帮我这个?我希望我的代码不难读。我添加了一些评论来解释什么是什么。我还是C的新手
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "difLvl.c"
int displayFiled(char **field); //prints out the map of the field
int combine(char answer, int answer1); //combines user input and field numeration
int Randomizer(int **mineArray); //generates random mine map
int difficulty();
int playGame();
int main(){
int playGame();
playGame();
system("PAUSE");
return 0;
}
int Randomizer(int **mineArray){
int difficulty();
int i, j;
srand(time(NULL));
int mines;
int placeMine;
int totalMines;
//int difLvl=2;
int difLvl=difficulty();
for(i=0, totalMines=0; i<10; i++){
for(j=0, mines=0; j<10 && mines<difLvl; j++){
placeMine= rand() % 2;
mineArray[i][j] = placeMine;
if(placeMine==1){
++mines;
};
};
totalMines+=mines;
};
return totalMines;
}
int displayFiled(char **field){
int i, j;
printf(" A B C D E F G H I J\n");
printf(" --------------------\n");
for (i=0; i<10; i++){
if (i==9){
printf("%d |", i+1);
}else{
printf("%d |", i+1);
};
for (j=0; j<10; j++){
printf("%c ", field[i][j]);
if (j==9){
printf("\n");
};
};
};
printf("\n");
return 0;
}
int playGame(){
int displayFiled(char **field);
int combine(char answer, int answer1);
int Randomizer(int ** mineArray);
char Y_char; //column as character (a, b, c etc.)
int X; //row
int Y; //Y_char converted to a number
int **mineArray; //stores the map of mines
char **fieldDisplay; //prints out the map of the field
int i, j; //counters
int life=1;
int movePl=0; //no dying on the first move
int globalMines; //number of mines placed
int openedFields=0; //counts the number of fields opened
//int difLvl;
//int difficulty();
//difLvl= difficulty();
/*disabled the trhee lines above while I was trying some solutions*/
/*int difficulty() is now called from int Randomizer()*/
system("cls");
/*Allocates memory to mineArray*/
mineArray= (int*)calloc(10, sizeof(int));
for(i = 0; i < 10; i++){
mineArray[i] = calloc(10, sizeof(int));
};
/*Allocates memory to fieldDisplay*/
fieldDisplay= (int*)calloc(10, sizeof(int));
for(i = 0; i < 10; i++){
fieldDisplay[i] = calloc(10, sizeof(int));
};
/*default look of fields with ?*/
for (i=0; i<10; i++){
for (j=0; j<10; j++){
fieldDisplay[i][j]='?';
};
};
globalMines= Randomizer(mineArray);
while(life==1 && openedFields<(100-globalMines)){
/*for checking purposes only*/
/*for (i=0; i<10; i++){
for (j=0; j<10; j++){
printf("%d ", mineArray[i][j]);
if (j==9){
printf("\n");
};
};
};*/
//printf("\nDifficulty level %d\n", difLvl);
printf("Total number of mines is %d\n\n", globalMines);
printf("\tMove nr. %d\n\n", movePl+1);
displayFiled(fieldDisplay);
printf("Which field do You want to activate?\nType first the letter, space and then the number (A 1, B 10 etc.)\n");
scanf("%c %d", &Y_char, &X);
if (Y_char >= 'A' && Y_char <= 'Z'){
Y = Y_char - 'A';
}else if(Y_char >= 'a' && Y_char <= 'z'){
Y = Y_char - 'a';
};
/*checks if a field is a mine*/
/*X-1 because the player chooses from 1 to 10*/
if (mineArray[X-1][Y]==0 && fieldDisplay[X-1][Y]=='?'){
movePl++;
fieldDisplay[X-1][Y]='0';
openedFields=openedFields+1;
OPEN : if (((X-2)<10) && ((X-2)>=0)){
if (mineArray[X-2][Y]==0 && fieldDisplay[X-2][Y]=='?'){
fieldDisplay[X-2][Y]='0';
openedFields=openedFields+1;
};
};
if ((X<10) && (X>=0)){
if (mineArray[X][Y]==0 && fieldDisplay[X][Y]=='?'){
fieldDisplay[X][Y]='0';
openedFields=openedFields+1;
};
};
if (((Y+1)<10) && ((Y+1)>=0)){
if (mineArray[X-1][Y+1]==0 && fieldDisplay[X-1][Y+1]=='?'){
fieldDisplay[X-1][Y+1]='0';
openedFields=openedFields+1;
};
};
if (((Y-1)<10) && ((Y-1)>=0)){
if (mineArray[X-1][Y-1]==0 && fieldDisplay[X-1][Y-1]=='?'){
fieldDisplay[X-1][Y-1]='0';
openedFields=openedFields+1;
};
};
system("cls"); //clears console screen
}else if (mineArray[X-1][Y]==0 && fieldDisplay[X-1][Y]=='0'){
system("cls");
printf("You can't choose an already opened field!\n\n");
}else if(mineArray[X-1][Y]==1 && movePl==0){
/*only activates on the first turn if players hits mine*/
movePl++;
mineArray[X-1][Y]= 0;
fieldDisplay[X-1][Y]='0';
globalMines=globalMines-1;
goto OPEN;
system("cls");
}else{
system("cls");
printf("YOU DIED ! YOU DIED ! YOU DIED !\n\n");
printf("Moves successfully made: %d\n\n", movePl-1);
fieldDisplay[X-1][Y]='1';
displayFiled(fieldDisplay);
--life;
};
};
if(openedFields==(100-globalMines)){
printf("Congratulations! You won the game!\n\n");
displayFiled(fieldDisplay);
};
for(i = 0; i < 10; i++){
free(mineArray[i]);
};
free(mineArray);
for(i = 0; i < 10; i++){
free(fieldDisplay[i]);
};
free(fieldDisplay);
return 0;
}
difLvl.c 文件:
#include <stdio.h>
#include <stdlib.h>
int difficulty(){
int difLvl;
while(1){
printf("Please choose a difficulty level:\n");
printf("Easy-1\nNormal-2\nNightmare-3\n");
printf("Your answer: ");
scanf(" %d", &difLvl);
if(difLvl>=1 && difLvl<=3){
break;
}else{
system("cls");
continue;
};
};
system("cls");
return difLvl;
}
我创建了它,因为我认为也许 main() 中的代码太多,这也许就是难度选项无法正常工作的原因。
编辑 提示用户输入难度级别后,创建了矿山地图,但选择了一个文件后,程序崩溃了。
已解决 scanf("%c %d", &Y_char, &X); 变成 scanf(" %c %d", &Y_char, &X);
首先,你没有正确分配你的二维字段。 "outer" 字段必须包含 int *
,而不仅仅是 int
:
mineArray = calloc(10, sizeof(*mineArray));
for (i = 0; i < 10; i++) {
mineArray[i] = calloc(10, sizeof(*mineArray[i]));
}
分段错误的另一个潜在来源是 Y
可能最终未初始化,因此具有垃圾值。原因是 scanf
:
scanf("%c %d", &Y_char, &X);
大多数 scanf
格式在转换前跳过白色 space,但 %c
不会。当您希望阅读一个字母时,很可能您将换行符读作 %c
的字符。因为换行符是白色的 space,你可以通过在 %c
之前放置一个 space 来修复它?格式:
scanf(" %c %d", &Y_char, &X);
(我说热修复,因为它不是一个好的解决方案。scanf
不特别对待换行符;它们只是 space。更好的解决方案可能是首先用 fgets
读取一行,然后用 sscanf
扫描它。至少你可以把每一行都当作 frash 输入。(你的输入确实应该确保忽略错误的输入。)
最后,奇怪的是你包含了一个*.c
文件。如果你想将 ypur 项目分布在各种文件上,这基本上是个好主意,你应该为每个 *.c
编写一个头文件,它有文件的接口。在其他 *.c
个文件中包含头文件;分别将 *.c
个文件编译成对象,然后 link 它们。这个过程通常由 Makefiles 或 Projects 控制。