使用memcpy将1KB Byte数组复制到单个变量。寻找更聪明的方式

时间:2013-09-03 09:01:39

标签: c++ pointers memcpy

我有一个大小为1024的字节数组arr和4个变量,我要复制数组arr的开头。 后来我想从数组中读取更多数据。实现这一目标的最佳和最有活力的方法是什么?目前我只是静态复制字节。也许是一个自动设置到当前读数位置的指针? 谢谢!

unsigned char arr[1024];
unsigned char field1 = 0;
unsigned int field2 =0;
unsigned int field3 = 0;
unsigned char field4 = 0;

memcpy(&field1, arr,    sizeof(field1));
memcpy(&field2, arr[1], sizeof(field2));
memcpy(&field3, arr[5], sizeof(field3));
memcpy(&field4, arr[9], sizeof(field4));

5 个答案:

答案 0 :(得分:2)

你的意思是:

  char *curr = arr; 

  memcpy(&field1, curr,    sizeof(field1));
  curr += sizeof(field1); 
  memcpy(&field2, curr, sizeof(field2));
  curr += sizeof(field2); 
  ... 

当然,你可以更进一步,制作一张桌子:

struct Table
{
     void    *field;
     size_t   size;
} table = 
{
     { &field1, sizeof(field1) }, 
     { &filed2, sizeof(field2) }, 
      ... 
 };

 curr = arr;
 for(int i = 0; i < sizeof(table)/sizeof(table[0]); i++)
 {
     memcpy(table[i].field, curr, table[i].size);
     curr += table[i].size;
 }

答案 1 :(得分:0)

创建一个结构:

struct s{
   unsigned char field1;
   unsigned int field2;
   unsigned int field3;
   unsigned char field4;
}__attribute__((packed));

然后:

struct s* ptr;
ptr = arr;

这会将数组中的数据解释为此结构。然后,如果要读取下一条记录,只需递增指针。请注意,我正在使用自定义GCC扩展,如果您不使用GCC,请查找编译器的扩展名。

答案 2 :(得分:0)

如何使用可变参数模板函数提供帮助。

size_t copy_array_r (const void *, size_t, size_t accum) {
    return accum;
}

template <typename T, typename... Params>
size_t copy_array_r (const void *arr, size_t sz, size_t accum,
                   T &arg, Params... parameters) {
    if (sz < sizeof(T)) {
        return copy_array_r(0, 0, accum + sizeof(T), parameters...);
    }
    const char *arrp = static_cast<const char *>(arr);
    std::copy(arrp, arrp + sizeof(T), &arg);
    return copy_array_r(arrp + sizeof(T), sz - sizeof(T), accum + sizeof(T),
                        parameters...);
}

template <typename... Params>
size_t copy_array (const void *arr, size_t sz, Params... parameters) {
    size_t bytes_copied = copy_array_r(arr, sz, 0, parameters...);
    if (bytes_copied > sz) {
        throw std::invalid_argument("insufficient size");
    }
    return bytes_copied;
}

然后像这样使用它:

bytes_copied = copy_array(arr, sizeof(arr), field1, field2, field3, field4);

答案 3 :(得分:0)

我的看法:

unsigned int copy_data( void* from, unsigned int size, void* to )
{
   memcpy( from, to, size);
   return size;
}

unsigned int offset = 0;
unsigned char arr[1024];
unsigned char field1 = 0;
unsigned int field2 =0;
unsigned int field3 = 0;
unsigned char field4 = 0;

offset += copy_data( arr + offset, &field1, sizeof(field1) );
offset += copy_data( arr + offset, &field2, sizeof(field2) );
offset += copy_data( arr + offset, &field3, sizeof(field3) );
offset += copy_data( arr + offset, &field4, sizeof(field4) );

然后可以使用偏移量来从缓冲区中进行下一次读取。

如果你觉得(但那变得丑陋)你可以MACROize:

#define COPY_TO_FIELD( arr, off, field_number ) \ 
 (offset) += copy_data( (arr) + (offset), &field##field_number, sizeof(field##field_number))

COPY_TO_FIELD( arr, offset, 1);
COPY_TO_FIELD( arr, offset, 2);
COPY_TO_FIELD( arr, offset, 3);
COPY_TO_FIELD( arr, offset, 4);

答案 4 :(得分:-1)

在结构中对变量进行分组:

typedef struct {
    unsigned char f1;
    unsigned int  f2, f3;
    unsigned char f4;
} __attribute__((packed)) mystruct_t;

unsigned char buffer[1024];
/* Track your position in the buffer: */
unsigned char *pos = buffer;

/* Map your variables on the buffer: */
mystruct_t *first_tuple = (mystruct_t *) pos;
/* Advance your position in the buffer: */
pos += sizeof *first_tuple;