关于C#:使用fread()将二进制文件转换为结构的麻烦

Trouble using fread() to convert a binary file to a struct

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

结构:

1
2
3
4
struct MdbRec {
    char name[16];
    char  msg[24];
};

相关代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
    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\
"
);
    }
    free(data);
    removeAllNodes( &db );

addFront()和addAfter是链表结构的方法,可为数据字段分配空间。

当我用Valgrind运行它时,表明我已经成功分配了2个内存。 一种显然是数据变量。 其他568个字节,这让我很困惑。 Valgrind说错误是我运行fread()时产生的。


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

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


这是内存泄漏:

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

因为message现在指向data,并且不再指向刚无法访问的malloc() d内存。 我怀疑您实际上打算将data复制到message

1
*message = *data;

其他要点:

  • 在使用fopen()之前,请检查其结果。
  • 似乎没有理由不为data使用堆栈分配的对象,这将避免不必要的动态分配管理。
  • 指定要读取的对象40的大小的fread()参数容易出错。 对struct MdbRec的任何更改都会破坏它:请使用sizeof(struct MdbRec)
  • 强制转换malloc()的返回值不是必需的,而且可能很危险(请参阅是否强制转换malloc的结果?)。