使用fread()将二进制文件转换为结构时遇到问题

时间:2012-10-21 19:56:00

标签: c struct binaryfiles fread

我在使用fread()将二进制文件转换为结构的链接列表时遇到了麻烦。

结构:

struct MdbRec {
    char name[16];
    char  msg[24];
};

相关代码:

    FILE *file;
    file = fopen( argv[1], "rb" );

    struct List db;
    initList(&db);
    struct MdbRec *data = (struct MdbRec *)malloc(sizeof(struct MdbRec));
    struct Node *last;
    while( fread( data, 40, 1, file ) )
    {
            struct MdbRec *message = (struct MdbRec *)malloc(sizeof(struct MdbRec));
            message = data;
            if( !db.head )
            {
                    last = addFront( &db, message );
                    db.head = last;
            }
            else
                    last = addAfter( &db, last, message );
            if( fseek( file, 40, SEEK_CUR ) != 0)
                    break;
            printf("read\n");
    }
    free(data);
    removeAllNodes( &db );

addFront()和addAfter是mallocs为数据字段留出空间的链表结构的方法。

当我用Valgrind运行它时,它表明我已经成功地分配了2个内存。一个显然是数据变量。其他568个字节对我来说非常混乱。 Valgrind说错误来自于我运行fread()。

2 个答案:

答案 0 :(得分:1)

这是内存泄漏:

struct MdbRec *message = (struct MdbRec *)malloc(sizeof(struct MdbRec));
message = data;

因为message现在指向data并且不再指向刚才malloc() d内存,现在无法访问。我怀疑你实际上是想复制 datamessage

*message = *data;

其他要点:

  • 使用前检查fopen()的结果。
  • 似乎没有理由不为data使用堆栈分配对象,这样可以避免对其进行不必要的动态分配管理。
  • 指定要读取的对象大小fread()的{​​{1}}参数容易出错。对40的任何更改都会破坏它:改为使用struct MdbRec
  • 投放sizeof(struct MdbRec)的返回值不是必需的,也可能是危险的(请参阅Do I cast the result of malloc?)。

答案 1 :(得分:1)

struct MdbRec *message = (struct MdbRec *)malloc(sizeof(struct MdbRec));
message = data;

您重新分配了struct MdbRec并将其丢弃。