带有 malloced 嵌套结构的 fwrite 和 fread 没有预期的行为

fwrite and fread with malloced nested struct does not have expected behaviour

我有一个用 malloc 分配的嵌套结构指针数组。我想在二进制文件中打印数组,然后再次将其加载到该结构中以粉碎现有记录。这是我的结构数组:

struct viaje {
    char *identificador;
    char *ciudadDestino;
    char *hotel;
    int numeroNoches;
    char *tipoTransporte;
    float precioAlojamiento;
    float precioDesplazamiento;
};

struct cliente {
    char *dni;
    char *nombre;
    char *apellidos;
    char *direccion;
    int totalViajes;
    struct viaje *viajes;
} *clientes;

我正在尝试将其打印在二进制文件中,例如:

for (i = 0; i < MAX_TAM_CLIENTES; i++) {
    fwrite(&clientes[i], sizeof(struct cliente)-(sizeof(struct viaje)*MAX_TAM_VIAJES_CLIENTE), 1, fp_guardarCargarEstado);

    for (j = 0; j < clientes[i].totalViajes; j++) {
        fwrite(&clientes[i].viajes[j], sizeof(struct viaje), 1, fp_guardarCargarEstado);
    }
}

其中:

MAX_TAM_CLIENTES 是一个定义。是数组的最大大小 clientes,
MAX_TAM_VIAJES_CLIENTE 是一个定义。数组 viajes 的最大大小是否在一个 clientes

此外,我尝试加载此二进制数据,如:

    for (i = 0; i < MAX_TAM_CLIENTES; i++) {
        clientes = (struct cliente *)realloc(clientes, (totalClientes+1)*sizeof(struct cliente));
        clientes[totalClientes].dni = (char *)malloc((MAX_TAM_DNI+1)*sizeof(char));
        clientes[totalClientes].nombre = (char *)malloc((MAX_TAM_NOMBRE+1)*sizeof(char));
        clientes[totalClientes].apellidos = (char *)malloc((MAX_TAM_APELLIDOS+1)*sizeof(char));
        clientes[totalClientes].direccion = (char *)malloc((MAX_TAM_DIRECCION+1)*sizeof(char));

        fread(&clientes[i], sizeof(struct cliente)-(sizeof(struct viaje)*MAX_TAM_VIAJES_CLIENTE), 1, fp_guardarCargarEstado);

        for (j = 0; j < clientes[i].totalViajes; j++) {
            clientes[i].viajes = (struct viaje *)realloc(clientes[i].viajes, (j+1)*sizeof(struct viaje));
            clientes[i].viajes[j].identificador = (char *)malloc((MAX_TAM_IDENTIFICADOR+1)*sizeof(char));
            clientes[i].viajes[j].ciudadDestino = (char *)malloc((MAX_TAM_CIUDAD_DESTINO+1)*sizeof(char));
            clientes[i].viajes[j].hotel = (char *)malloc((MAX_TAM_HOTEL+1)*sizeof(char));
            clientes[i].viajes[j].tipoTransporte = (char *)malloc((MAX_TAM_TIPO_TRANSPORTE+1)*sizeof(char));

            fread(&clientes[i].viajes[j], sizeof(struct viaje), 1, fp_guardarCargarEstado);
        }
    }

其中:

MAX_TAM_* 是定义。它们是每个字段的最大大小。

但我不知道 fwrite 是否保存了良好的数据,因为当我尝试加载它时,程序崩溃并且没有加载数据。

不知道怎么会有错。有什么想法吗?

谢谢。

您不能使用 fwrite 保存这些结构的全部内容并使用 fread 读回它们,因为它们包含指向字符串的指针,而不是实际字符。

有两种方法可以实现您的目标:

  • 将内容保存为标准格式的文本,例如 XML 或简单的 CSV,其中每个条目都写在一行中,不同的字段由 , 分隔。
  • 更改结构以将字符串存储为 char 的数组而不是指向已分配存储的指针。 If you open the files as binary, you should be able to write the structures and read them back with害怕`。

但是请注意,后一种方法不如文本方法灵活:

  • 如果更改结构,则无法再使用新版本的程序读取以前保存的内容。
  • 二进制格式可能无法移植到其他架构,例如智能手机,因为 int 的表示可能不同。
  • 成员 struct viaje *viajes; 也必须替换为没有任何指针的实际结构。