2012-05-01 7 views
1

データのバイナリチャンクを保持するバッファが構造体の配列にコピーされると仮定します(各構造体はチャンクを表します)。バッファの各チャンクは20バイトです。サイズのハッシュ値は、オフセット情報のため、8バイト、8:構造体をコピーするときに正しい値を取得しない

は、構造体の定義のthats:

typedef struct{ 
    khint_t hash; // 4                                        
    long int offset_start; // 8                                      
    size_t size; // 8                                         
} header_offset, *offset_p; 

をしていただきました下記行うことになっていますコードです:

offset_p *offsets; 
    size_t s= HEADER_OFFSET_SIZE; 

    header_offset t_offsets[n_files];                      

    for (i=0; i< n_files; i++){ 
    memcpy(&t_offsets[i].hash, buff, sizeof(khint_t)); 
    buff+= sizeof(khint_t); 
    memcpy(&t_offsets[i].offset_start, buff, sizeof(long int)); 
    buff+= sizeof(long int); 
    memcpy(&t_offsets[i].size, buff, sizeof(size_t)); 
    buff+= sizeof(size_t); 

    printf("hash read: %p\n", t_offsets[i].hash); 
    printf("offset start read: %p\n", t_offsets[i].offset_start); 
    printf("offset size read: %p\n", t_offsets[i].size); 
    } 

    memmove(offsets, t_offsets, sizeof(header_offset)*n_files); 

    buff-= s*n_files; 
    free(buff);                                         

    return offsets; 

塊を直接header_p *にコピーするのに苦労していたので、一時的な構造体配列をバッファからコピーしてからheader_p *にコピーしました。一時的な構造体配列を使用せずにそれを行う。

printfsは正しいデータを出力しますが、この関数を呼び出すと返されるポインタの配列には正しいデータやループ内で出力されたデータが保持されません。

offset_pの配列に正しい値を保持しないポインタを使用しているかどうかを、コードなしで知りたいと思います。

+0

'sizeof(header_offset)'が20であることを確認しましたか?パディングのために、それは容易に24である可能性があります。 –

+0

これは、実際の構造体を扱うときに、idがバッファを扱うときにHEADER_OFFSET_SIZEを使用し、sizeof(header_offset)を使用する理由です。 – Smokie

+0

ああ、良い。あなたはそれを認識しています。ちょうど確かめたかった。 –

答えて

4

ませメモリーはmemmove()があなたのためにメモリを割り当てていない、offsetsのために割り当てられていない。

header_offset *オフセット=のmalloc(はsizeof(header_offset)* n_filesを)。あなたは t_offsetsの使用を返されるメモリを割り当てていることを考えると

は不要です:ちょうど直接offsetsを取り込みます。

EDIT:alkによってコメントとして

header_offset*[]を返すために:

header_offset** offsets = malloc(sizeof(header_offset*) * n_files); 
for (i=0; i< n_files; i++){ 
    *(offsets + i) = malloc(sizeof(header_offset)); 
    ... 
} 
+0

私がOPを理解する限り( 'header_offset'への)ポインタの配列への参照が返されます。あなたの解決策は' header_offset'の配列への参照を返します。 – alk

4

offsetsはおそらくポインタ、いない構造体の配列です。

memcopyはおそらくoffsetsのために割り当てられたメモリの最後を過ぎて大きなメモリチャンクを上書きするでしょう(どれだけのメモリが割り当てられているかはわかりませんが)。同様

for (i=0; i< n_files; i++){ 
    offsets[i] = malloc(sizeof(header_offset)); 
    memcpy(&(*offsets[i]).hash, buff, sizeof(khint_t)); 
    buff+= sizeof(khint_t); 

    memcpy(&(*offsets[i]).offset_start, buff, sizeof(long int)); 
    buff+= sizeof(long int); 

    memcpy(&(*offsets[i]).size, buff, sizeof(size_t)); 
    buff+= sizeof(size_t); 
} 
1

header_offsetに(当時offset_p *offsets; によって参照)自体が割り当てる必要がある配列をポインタの配列を返すには

offset_p *offsets = (offset_p*)malloc(sizeof(offset_p)*n_files); 

をそしてループ:

私がお勧めしたいです現在一時構造によって保持されているデータを保持するメモリとして使用します。後者は、offsetsが保持するポインタによる参照になります。

関連する問題