【问题标题】:Not getting the right values when copying structs复制结构时没有得到正确的值
【发布时间】:2012-05-11 08:55:52
【问题描述】:

保存二进制数据块的缓冲区应该被复制到结构数组中(每个结构代表一个块),缓冲区中的每个块是 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 的数组不保存正确的值。

【问题讨论】:

  • 你确认sizeof(header_offset)是20了吗?由于填充,它很可能是 24。
  • 这就是为什么 id 在处理缓冲区时使用 HEADER_OFFSET_SIZE 而在处理实际结构时使用 sizeof(header_offset)。
  • 啊,很好。你知道这一点。只是想确定一下。

标签: c pointers struct binary


【解决方案1】:

没有为offsets分配内存,memmove()没有为你分配内存:

header_offset* 偏移量 = malloc(sizeof(header_offset)*n_files);

鉴于您正在分配要返回的内存,因此不需要使用 t_offsets:只需直接填充 offsets

编辑:

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));
    ...
}

【讨论】:

  • 据我了解,OP 应返回对指针数组(指向 header_offset)的引用,您的解决方案将返回对 header_offset 数组的引用。
【解决方案2】:

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);
}

【讨论】:

    【解决方案3】:

    要返回指向header_offset 的指针数组,需要分配数组本身(然后由offset_p *offsets; 引用)以及保存临时结构当前保存的数据的内存。然后后者将被offsets 持有的指针引用。

    【讨论】:

      猜你喜欢
      • 2021-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-20
      • 1970-01-01
      • 2022-10-19
      • 2022-08-16
      • 2012-12-13
      相关资源
      最近更新 更多