【问题标题】:fwrite and fread with malloced nested struct does not have expected behaviour带有 malloced 嵌套结构的 fwrite 和 fread 没有预期的行为
【发布时间】:2018-03-24 17:40:08
【问题描述】:

我有一个用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的最大大小是多少

另外,我尝试像这样加载这个二进制数据:

    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 是否保存好数据,因为当我尝试加载它时,程序崩溃并且没有加载数据。

我不知道那里怎么可能出错。有什么想法吗?

谢谢。

【问题讨论】:

  • “Anidated”不是我知道的英文单词(但我不是母语人士)。西班牙语的一种翻译似乎是“嵌套的”。你是这个意思吗?很抱歉没有帮助解决实际问题。
  • 是的,没错。我想说嵌套,问题的标题已经修改。非常感谢。没问题,不要担心问题:)
  • 提示:最好使用像int32_t 这样的固定宽度类型而不是int 来保存整数
  • 好的,我会注意的,谢谢

标签: c struct malloc fwrite fread


【解决方案1】:

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

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

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

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

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

【讨论】:

  • 哦,好的,非常感谢!我坚持认为这是可能的。我会认真听取您的建议。
猜你喜欢
  • 2016-03-14
  • 2018-03-12
  • 2012-09-28
  • 2012-03-12
  • 1970-01-01
  • 2023-03-10
  • 2017-04-20
  • 2021-11-03
  • 1970-01-01
相关资源
最近更新 更多