C 将结构从main()传递给辅助函数时发生SEGFULT
我正试图用C写一个简单的游戏,但我遇到了一个错误,不知道为什么 以下是该程序的代码:C 将结构从main()传递给辅助函数时发生SEGFULT,c,struct,segmentation-fault,pass-by-value,pass-by-pointer,C,Struct,Segmentation Fault,Pass By Value,Pass By Pointer,我正试图用C写一个简单的游戏,但我遇到了一个错误,不知道为什么 以下是该程序的代码: #include <stdio.h> #include <string.h> #define MAX_PLYS_PER_GAME (1024) #define MAX_LEN (100) typedef struct { char positionHistory[MAX_PLYS_PER_GAME][MAX_LEN]; } Game; void getInitialGame(
#include <stdio.h>
#include <string.h>
#define MAX_PLYS_PER_GAME (1024)
#define MAX_LEN (100)
typedef struct {
char positionHistory[MAX_PLYS_PER_GAME][MAX_LEN];
} Game;
void getInitialGame(Game * game) {
memset(game->positionHistory, 0, MAX_PLYS_PER_GAME*MAX_LEN*sizeof(char));
}
void printGame(Game game) {
printf("Game -> %p (%d)\n", &game, sizeof(game));
fflush(stdout);
}
int hasGameEnded(Game game) {
printGame(game);
return 0;
}
int main(int argc, char *argv[]) {
Game game;
getInitialGame(&game);
if (hasGameEnded(game))
return -1;
return 0;
}
#包括
#包括
#定义每个游戏的最大游戏数(1024)
#定义最大长度(100)
类型定义结构{
char positionHistory[MAX_PLYS_PER_GAME][MAX_LEN];
}游戏;
无效getInitialGame(游戏*游戏){
memset(游戏->位置历史,0,每个游戏的最大值*最大值*大小(字符));
}
无效打印游戏(游戏){
printf(“游戏->%p(%d)\n)”,&Game,sizeof(游戏));
fflush(stdout);
}
int hasGameEnded(游戏){
印刷游戏(游戏);
返回0;
}
int main(int argc,char*argv[]){
游戏;
getInitialGame(&game);
如果(游戏结束(游戏))
返回-1;
返回0;
}
我尝试使用gdb进行调试,但结果并没有让我走得太远:
C:\Users\test>gdb test.exe
GNU gdb 5.1.1 (mingw experimental)
<snip>
This GDB was configured as "mingw32"...
(gdb) run
Starting program: C:\Users\test/test.exe
Program received signal SIGSEGV, Segmentation fault.
0x00401368 in main (argc=1, argv=0x341c88) at fast-chess-bug.c:29
29 if (hasGameEnded(game))
(gdb) bt
#0 0x00401368 in main (argc=1, argv=0x341c88) at fast-chess-bug.c:29
C:\Users\test>gdb test.exe
GNU gdb 5.1.1(mingw实验)
此GDB已配置为“mingw32”。。。
(gdb)运行
启动程序:C:\Users\test/test.exe
程序接收信号SIGSEGV,分段故障。
快速国际象棋错误处的主代码0x00401368(argc=1,argv=0x341c88)。c:29
29如果(游戏结束(游戏))
(gdb)英国电信
#快速国际象棋错误处的0 0x00401368主(argc=1,argv=0x341c88)。c:29
这可能是堆栈溢出(真的!),尽管我不确定
游戏代码>在main()
中。这意味着所有102400字节的game
都在堆栈中
printGame
和hasGameEnded
都要玩Game游戏
,而不是Game*游戏
。也就是说,他们得到的是游戏的副本,而不是指向现有游戏的指针。因此,无论何时调用其中一个,都会在堆栈上转储另外102400个字节李>
我猜对printGame
的调用正在以某种方式破坏堆栈,从而导致hasGameEnded
调用出现问题
据我所知,最简单的修复方法(不涉及动态内存分配,长期而言可能更好)是:
移动游戏
在main()
之外,例如,在int main(…)
正上方的行。这样,它将位于数据段中,而不是堆栈上
将printGame
和hasGameEnded
更改为使用Game*
:
void printGame(Game * game) {
printf("Game -> %p (%d)\n", game, sizeof(Game));
fflush(stdout);
}
int hasGameEnded(Game * game) {
printGame(game);
return 0;
}
这应该会让您继续前进。您可能会耗尽堆栈空间
C是传递值。所以这个代码
int hasGameEnded(Game game)
创建整个struct{}游戏的副本
,很可能在堆栈上
如果以下代码正常工作,则堆栈空间不足:
...
void printGame(Game *game) {
printf("Game -> %p (%zu)\n", game, sizeof(*game));
fflush(stdout);
}
int hasGameEnded(Game *game) {
printGame(game);
return 0;
}
int main(int argc, char *argv[]) {
Game game;
getInitialGame(&game);
if (hasGameEnded(&game))
return -1;
return 0;
}
仔细注意这些变化。它不再将整个结构传递给hasGameEnded
,而是只传递结构的地址。该更改会沿着调用堆栈向下流动,最终会更改到printGame()
还要注意的是,由于大小不能为负数,所以我和随意将它设为unsigned的u
。我无法复制它。为了有效调用函数,printGame和HasGameEnd应该使用指向游戏的指针(如getInitialGame)。您应该将printGame()
函数中的打印说明符从%d
更改为%lu
。欢迎!谢谢你在你的问题中加入细节——不是每个人都这样做。查看更多有关社区工作方式的信息,并享受您的住宿!谢谢你们的反馈,伙计们!好的,您的程序编译和运行没有任何问题(只是一个警告,关于对sizeof(game)
使用%d
格式而不是%ld
。除了按值将完整结构传递给hasGameEnded()
和printGame()之外
functions,我看不到您的代码中有任何不规则的地方(您正在复制堆栈上的100Kb结构以将其传递给任何一个函数)堆栈溢出中的第一个post实际上是堆栈溢出!哦,讽刺的是…谢谢您的帮助!:)