malloc中的Sigsegv
我想保存一个包含用作动态数组的指针的结构,但是当我加载该结构并malloc该指针时,它失败了 我有三个结构(Orientation、ShipType、Status和PlayerType是枚举,可以用Int替换): 我声明了一个由2个玩家组成的数组,如下所示:malloc中的Sigsegv,c,pointers,memory,struct,malloc,C,Pointers,Memory,Struct,Malloc,我想保存一个包含用作动态数组的指针的结构,但是当我加载该结构并malloc该指针时,它失败了 我有三个结构(Orientation、ShipType、Status和PlayerType是枚举,可以用Int替换): 我声明了一个由2个玩家组成的数组,如下所示:Player-players[2]并初始化其属性。然后我想将结构保存在一个文件中,以便以后加载它。 此外,我使用Map struct作为二维动态数组,使用了四个函数: void mallocMap(Map* map, int width, i
Player-players[2]编码>并初始化其属性。然后我想将结构保存在一个文件中,以便以后加载它。
此外,我使用Map struct作为二维动态数组,使用了四个函数:
void mallocMap(Map* map, int width, int height)
{
map->cases = malloc(sizeof(int) * width * height);
map->width = width;
map->height = height;
if (map->cases == NULL)
{
printf("Erreur d'allocation de memoire\n");
exit(0);
}
}
void freeMap(Map* map)
{
free(map->cases);
}
int getMapValue(Map map, int x, int y)
{
return *(map.cases + y*map.width + x);
}
void setMapValue(Map* map, int value, int x, int y)
{
*(map->cases + y*map->width + x) = value;
}
因此,当我存储结构时,map.cases
只是一个指针,我需要将值分别存储在它的地址,如下所示:
int save(Player players[2])
{
int* i;
FILE* file = NULL;
file = fopen("save.txt","w+");
if (file != NULL)
{
fwrite(players, sizeof(Player), 2, file);
fwrite(players[0].map[0].cases, sizeof(int), players[0].map[0].width * players[0].map[0].height, file);
fwrite(players[0].map[1].cases, sizeof(int), players[0].map[1].width * players[0].map[1].height, file);
fwrite(players[1].map[0].cases, sizeof(int), players[1].map[0].width * players[1].map[0].height, file);
fwrite(players[1].map[1].cases, sizeof(int), players[1].map[1].width * players[1].map[1].height, file);
}
else
{
// error
}
fclose(file);
return 1;
}
每个玩家有2张地图,因此在最后有4张地图要存储。
问题出在我的load()
函数中:
int load(Player players[2])
{
FILE* file = NULL;
file = fopen("save.txt","r");
if (file != NULL)
{
int *i;
fread(players, sizeof(Player), 2, file);
mallocMap(&players[0].map[0], players[0].map[0].width, players[0].map[0].height);
mallocMap(&players[0].map[1], players[0].map[1].width, players[0].map[1].height);
mallocMap(&players[1].map[0], players[1].map[0].width, players[1].map[0].height);
mallocMap(&players[1].map[1], players[1].map[1].width, players[1].map[1].height);
fread(players[0].map[0].cases, sizeof(int), players[0].map[0].width * players[0].map[0].height, file);
fread(players[0].map[1].cases, sizeof(int), players[0].map[1].width * players[0].map[1].height, file);
fread(players[1].map[0].cases, sizeof(int), players[1].map[0].width * players[1].map[0].height, file);
fread(players[1].map[1].cases, sizeof(int), players[1].map[1].width * players[1].map[1].height, file);
}
else
{
// error
}
fclose(file);
return 1;
}
当我调用mapAlloc()
时,它无法分配内存并且退出(0)
;我的程序停止。您声明的load
函数看起来不正确:
int load(Player* players[2])
这需要一个指向播放器的指针数组,而保存
例程需要一个播放器数组(即播放器播放器[2]
)。您可能需要将其更改为:
int load(Player players[2])
您还将值读回了错误的地址:
for(i = players[0]->map[0].cases; i < players[0]->map[0].cases + players[0]->map[0].width * players[0]->map[0].height; i++)
fread(&i, sizeof(int), 1, file);
这将把读入数组的int
此外,这里不需要使用循环来读/写单个int。只需执行一次读/写操作,传入要读/写的值的数量
因此,节约将是:
fwrite(players[0].map[0].cases, sizeof(int), players[0].map[0].width * players[0].map[0].height, file);
fwrite(players[0].map[1].cases, sizeof(int), players[0].map[1].width * players[0].map[1].height, file);
fwrite(players[1].map[0].cases, sizeof(int), players[1].map[0].width * players[1].map[0].height, file);
fwrite(players[1].map[1].cases, sizeof(int), players[1].map[1].width * players[1].map[1].height, file);
fread(players[0].map[0].cases, sizeof(int), players[0].map[0].width * players[0].map[0].height, file);
fread(players[0].map[1].cases, sizeof(int), players[0].map[1].width * players[0].map[1].height, file);
fread(players[1].map[0].cases, sizeof(int), players[1].map[0].width * players[1].map[0].height, file);
fread(players[1].map[1].cases, sizeof(int), players[1].map[1].width * players[1].map[1].height, file);
装载方式为:
fwrite(players[0].map[0].cases, sizeof(int), players[0].map[0].width * players[0].map[0].height, file);
fwrite(players[0].map[1].cases, sizeof(int), players[0].map[1].width * players[0].map[1].height, file);
fwrite(players[1].map[0].cases, sizeof(int), players[1].map[0].width * players[1].map[0].height, file);
fwrite(players[1].map[1].cases, sizeof(int), players[1].map[1].width * players[1].map[1].height, file);
fread(players[0].map[0].cases, sizeof(int), players[0].map[0].width * players[0].map[0].height, file);
fread(players[0].map[1].cases, sizeof(int), players[0].map[1].width * players[0].map[1].height, file);
fread(players[1].map[0].cases, sizeof(int), players[1].map[0].width * players[1].map[0].height, file);
fread(players[1].map[1].cases, sizeof(int), players[1].map[1].width * players[1].map[1].height, file);
编译代码时,不应出现任何警告。如果存在任何错误,您可能正在做一些需要修复的错误。您无法加载保存的指针并使用它们。在读取过程中,必须将指针设置为适当的值。这称为序列化和反序列化。结构中的指针不容易恢复。你必须努力工作。即使是写作也不平凡。你必须确保指针指向的数据被写入。但是如果我加载指针,它仍然会有它以前的地址,我需要一个新的地址,所以当我调用mapAlloc时,它应该为指针分配内存并设置一个新的地址?这并不能解决这里的主要问题,但是读写数据要简单得多,谢谢,我会更新我的code@Drakalex请参阅我的编辑。您定义加载的方式也可能是错误的。此外,我这样声明了我的函数,因为当我保存结构时,我不需要“真正”的播放器,但我可以传递它的副本,所以我保存一个本地副本。但是,当我加载播放器时,我在一个函数中声明了包含2个播放器的数组,然后通过传递数组的地址调用load
函数。使用intload(Player-players[2])
,数组是本地的。还是我错了?@Drakalex将数组传递给函数时,实际上是在传递指向第一个元素的指针。您将看到调用函数中的更改。如果您显示从何处调用save
和load
,也会有所帮助。因此,发生了奇怪的事情:我在没有指针的情况下重写了load(),并且不再有sigsegv错误。但是现在我的malloc失败了,因为行if(map->cases==NULL)
在mallocMap
中为true,它退出了我的程序。但这很奇怪,因为我第一次尝试它时,所有4个malloc都工作了,我的游戏按预期加载。但无法复制它。