我在使用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()。
答案 0 :(得分:1)
这是内存泄漏:
struct MdbRec *message = (struct MdbRec *)malloc(sizeof(struct MdbRec));
message = data;
因为message
现在指向data
并且不再指向刚才malloc()
d内存,现在无法访问。我怀疑你实际上是想复制 data
到message
:
*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
并将其丢弃。