0

我正在做一个小项目,我想知道为什么这段代码会导致我的程序崩溃。

PLAYER_FILE_PATH -- "player.txt"

sprite=yoshi.bmp
width=64
height=64
frames=8
alignment=1
animate=1

程序

      FILE *pfile = fopen(PLAYER_FILE_PATH, "r");
if (!pfile)
{
    debug_printf("could not open player file for reading!\n");
    return;
}
fscanf(pfile, "sprite=%s\n\
               width=%d\n\
               height=%d\n\
               frames=%d\n\
               alignment=%d\n\
               animate=%d",
               player_entity.entity_sprite.imgloc,
               &player_entity.entity_sprite.width,
               &player_entity.entity_sprite.height,
               &player_entity.entity_sprite.frames,
               &player_entity.entity_sprite.oscdir,
               &player_entity.entity_sprite.osc);
fclose(pfile);
4

3 回答 3

4

我们需要查看您对 player_entity 的定义才能确定。您可能没有正确定义“imgloc”,它需要指向一些安全分配的内存。例如,除非 imgloc 正确初始化,否则以下定义​​将进行核心转储:

struct {
  struct {
    char *imgloc;
    int width;
    int height;
    int frames;
    int oscdir;
    int osc;
  } entity_sprite;
} player_entity;

如果您将上面的 imgloc 行替换为类似

char imgloc[100];

但是,我会非常小心地使用 fscanf 读取字符串,因为如果字符串太长,它会溢出给定的缓冲区。也许只为字符串部分尝试 fgets 而为其余部分尝试 fscanf 。

于 2013-02-14T12:26:01.490 回答
0

我的猜测是您没有使用 malloc 或堆栈创建缓冲区来保存 imgloc 的值。

于 2013-02-14T12:18:35.173 回答
0

一个好主意——一般来说——是在开发应用程序时使用内存调试器(例如 valgrind)。

这样,您可以从一开始就确保您的程序不会泄漏内存(稍后调试的噩梦),并且您可以检测到您不必访问的内存的读取或写入(这会导致段错误,使您的程序崩溃)。

在您的特定情况下,Valgrind 会提醒您正在写入您无权访问的内存地址 X(并且可能使用未初始化的内存),如果您使用调试信息进行编译,则会为您提供文件名和行号(-G)。在这种情况下,它会将您指向 fscanf - 所以您会仔细查看它。如果通过查看该行无法找到问题,则可以将其拆分为一个一个读取参数,直到它(可能)将您指向分配字符串的行。

虽然如果您不知道 char* 不分配任何内存(除了保留指针的大小),这不会解决问题,但它可以让您更好地了解从哪里开始查找。当然,现在你知道你需要保留内存,所以当你再次看到问题时,你会立即应用这些知识。

于 2013-02-14T13:59:37.760 回答