malloc中的Sigsegv

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

我想保存一个包含用作动态数组的指针的结构,但是当我加载该结构并malloc该指针时,它失败了

我有三个结构(Orientation、ShipType、Status和PlayerType是枚举,可以用Int替换):

我声明了一个由2个玩家组成的数组,如下所示:
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
函数。使用int
load(Player-players[2])
,数组是本地的。还是我错了?@Drakalex将数组传递给函数时,实际上是在传递指向第一个元素的指针。您将看到调用函数中的更改。如果您显示从何处调用
save
load
,也会有所帮助。因此,发生了奇怪的事情:我在没有指针的情况下重写了load(),并且不再有sigsegv错误。但是现在我的malloc失败了,因为行
if(map->cases==NULL)
mallocMap
中为true,它退出了我的程序。但这很奇怪,因为我第一次尝试它时,所有4个malloc都工作了,我的游戏按预期加载。但无法复制它。