2

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は、データフィールドのスペースをmallocするリンクリスト構造のメソッドです。

Valgrindで実行すると、2つのメモリ割り当てが正常に行われていることがわかります。1つは明らかにデータ変数です。他の568バイトとそれは私には非常に混乱しています。Valgrindは、fread()を実行したときにエラーが発生したと言います。

4

2 に答える 2

1

これはメモリリークです。

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

現在messageはdメモリを指してdataおり、もはや指していないため、malloc()到達できなくなりました。私はあなたが実際にコピー dataするつもりだったと思いますmessage

*message = *data;

その他のポイント:

  • fopen()使用前に結果を確認してください。
  • にスタック割り当てオブジェクトを使用しない理由はないようですdata。これにより、不必要な動的割り当て管理が回避されます。
  • 読み取るオブジェクトのfread()サイズを指定する引数は、40エラーが発生しやすいです。を変更するstruct MdbRecと破損しますsizeof(struct MdbRec)。代わりに使用してください。
  • の戻り値をキャストするmalloc()必要はなく、危険である可能性があります(mallocの結果をキャストしますか?を参照)。
于 2012-10-21T19:59:53.510 に答える
1
struct MdbRec *message = (struct MdbRec *)malloc(sizeof(struct MdbRec));
message = data;

を再割り当てしstruct MdbRecて破棄しました。

于 2012-10-21T19:59:55.557 に答える