1

データのバイナリ チャンクを保持するバッファーは、構造体の配列 (各構造体はチャンクを表す) にコピーされることになっています。バッファー内の各チャンクは 20 バイトで、最初の 4 バイトはハッシュ値を保持し、次にオフセット情報用の 8 バイトを保持します。 、次にサイズの 8:

それは構造体の定義です:

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の配列が正しい値を保持しない原因となるポインターの使用方法かどうかを知りたいです。

4

3 に答える 3

4

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

memcopy はおそらく、割り当てられたメモリの最後を超えた大きなメモリ チャンクを上書きしますoffsets(ただし、割り当てられたメモリの量はわかりません)。

私はお勧めします:

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

そして、ループ

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);
}
于 2012-05-01T21:16:08.413 に答える
4

offsetsにはメモリが割り当てられていません。メモリは割り当てられmemmove()ません:

header_offset* オフセット = malloc(sizeof(header_offset)*n_files);

返されるメモリを割り当てている場合、 の使用t_offsetsは不要ですoffsets。直接入力するだけです。

編集:

alkheader_offset*[]によってコメントされた a を返すには:

header_offset** offsets = malloc(sizeof(header_offset*) * n_files);
for (i=0; i< n_files; i++){
    *(offsets + i) = malloc(sizeof(header_offset));
    ...
}
于 2012-05-01T21:08:45.433 に答える
1

ポインタの配列を配列自体に返すには、一時構造体によって現在保持されているデータを保持するメモリだけでなく、header_offset割り当てられる (次に によって参照される) 必要があります。offset_p *offsets; 後者は、 が保持するポインタによる参照になりますoffsets

于 2012-05-01T21:21:24.607 に答える