c - 将结构从 main() 传递到辅助函数时出现段错误

标签 c struct segmentation-fault pass-by-value pass-by-pointer

我正在尝试用 C 语言编写一个简单的游戏,但出现了 SEGFAULT,我不知道为什么!

程序代码如下:

#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;
}

我尝试使用 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

最佳答案

这可能是堆栈溢出(真的!),虽然我不确定。

  1. 您正在 main() 中声明 Game game;。这意味着 game 的所有 102400 字节都在堆栈中。
  2. printGamehasGameEnded 都采用Game 游戏,而不是Game * 游戏。也就是说,他们得到的是 Game副本,而不是指向现有 Game指针。因此,无论何时调用其中任何一个,都会在堆栈上转储另外 102400 个字节。

我猜测对 printGame 的调用正在破坏堆栈,导致 hasGameEnded 调用出现问题。

我所知道的最简单的解决方法(不涉及动态内存分配,从长远来看可能更好)是:

  1. Game game; 移到 main() 之外,例如,移到 int main(...) 正上方的行。这样它将位于数据段中而不是堆栈中。
  2. 更改printGamehasGameEnded 以获取Game *:

    void printGame(Game * game) {
        printf("Game -> %p (%d)\n", game, sizeof(Game));
        fflush(stdout);
    }
    
    int hasGameEnded(Game * game) {
        printGame(game);
        return 0;
    }
    

这应该会让你继续前进。

关于c - 将结构从 main() 传递到辅助函数时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40094249/

相关文章:

c - 对 GOT 所做的更改是否预期在反向调试期间被撤销?

php - 如何通过 PKCS5_PBKDF2_HMAC 和 hash_hmac 在 C 和 php 中获得相同的输出

c - 将 char 指针作为结构成员写入文件问题

c - 超出了神秘的内存限制;埃拉托色尼算法筛分错误

c - C中向链表添加新节点的过程

c++ - 将布局映射到内存地址

c++ - 构造函数中对 (class)(type) 的调用不匹配

python - 如何解决使用Python ctypes调用rs232.c时出现段错误的问题?

c++ - 段错误和运算符重载

C语言读取分栏文本文件