我正在开发一个小项目,我想知道为什么这段代码导致我的程序崩溃。
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);
答案 0 :(得分: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其余部分。
答案 1 :(得分:0)
我的猜测是你没有使用malloc或堆栈创建一个缓冲区来保存imgloc的值。
答案 2 :(得分:0)
一般来说,一个好主意是在开发应用程序时使用内存调试器(例如valgrind)。
通过这种方式,您可以从一开始就确保您的程序不会泄漏内存(稍后调试的噩梦),并且您可以检测到您不必访问的内存的读取或写入(这会导致一个段错误,导致你的程序崩溃。)
在您的特定情况下,Valgrind会提醒您,您正在写入您无权访问的内存地址X(并且可能使用未初始化的内存),如果您编译,则会提供文件名和行号带有调试信息(-g)。在这种情况下,它会指向你fscanf - 所以你会仔细看看它。如果通过查看该行找不到问题,则将其拆分为逐个读取参数,直到它(可能)指向您指定字符串的行。
虽然如果你不知道char *没有分配任何内存(除了保留指针的大小)之外就不会解决问题,它会让你更好地知道去哪里开始寻找。当然,现在您知道需要保留记忆,所以当您再次看到问题时,您会立即应用这些知识。