3

Windowsの使用

だから私はバイナリファイルからunsignedintデータ値のリストを読んでいます。このファイルには、順番にリストされた多数のデータセットが含まれています。開始を指すchar*から単一のデータセットを読み取る関数は次のとおりです。

function read_dataset(char* stream, t_dataset *dataset){

    //...some init, including setting dataset->size;

    for(i=0;i<dataset->size;i++){
        dataset->samples[i] = *((unsigned int *) stream);
        stream += sizeof(unsigned int);
    }
    //...
}

このようなコンテキストでのread_datasetの場合:

//...
char buff[10000];
t_dataset* dataset = malloc( sizeof( *dataset) );
unsigned long offset = 0;

for(i=0;i<number_of_datasets; i++){

    fseek(fd_in, offset, SEEK_SET);

    if( (n = fread(buff, sizeof(char), sizeof(*dataset), fd_in)) != sizeof(*dataset) ){
        break;
    }

    read_dataset(buff, *dataset);

    // Do something with dataset here.  It's screwed up before this, I checked.


    offset += profileSize;
}
//...

私のループが番号2573を読み取るまで、すべてが順調に進みます。突然、ランダムで巨大な番号が吐き出され始めます。

たとえば、どうあるべきか

...
1831
2229
2406
2637
2609
2573
2523
2247
...

になります

...
1831
2229
2406
2637
2609
0xDB00000A
0xC7000009
0xB2000008
...

それらの16進数が疑わしいと思われる場合は、その通りです。変更された値の16進値は非常によく知られていることがわかります。

2573 -> 0xA0D
2523 -> 0x9DB
2247 -> 0x8C7

したがって、明らかにこの番号2573により、ストリームポインタが1バイトを取得します。これは、次のデータセットがロードされて解析されるまで続き、神はそれが番号2573を含むことを禁じています。これが発生するスポットをいくつかチェックしました。チェックした各スポットは2573から始まりました。

私はCの世界ではそれほど才能がないことを認めます。これを引き起こす可能性のあるものは、私には完全に不透明です。

4

2 に答える 2

11

メモリ内のバイトをどのように取得したか (ストリームが指している)、実行しているプラ​​ットフォームを指定していませんが、Windows で見つけても驚かず、C stdio ライブラリの呼び出しfopen(filename "r");Tryを使用しましたを使用してfopen(filename, "rb");。Windows (および MS-DOS) では、fopen() は、ファイル モードに "b" を追加しない限り、ファイル内の MS-DOS の行末 "\r\n" (hex 0x0D 0x0A) を Unix スタイルの "\n" に変換します。バイナリを示します。

于 2009-10-21T22:12:07.557 に答える
0

いくつかの無関係なポイント。

sizeof(*dataset) は、あなたが思っていることをしません。

すべての読み取りでシークを使用する必要はありません

パラメーターを 1 つだけ受け取る関数を呼び出す方法がわかりませんが、パラメーターを 2 つ指定しています (または、コンパイラが反対しない理由が少なくともわかりません)。

于 2009-10-21T22:09:06.690 に答える