-2

I have various structures ( comprised of integral types and arrays of integral types ) and an array of unsigned chars that I want to add to a vector of unsigned chars.

So, given the following pseudocode:

struct
{
short x;
short sz;
unsigned char y;
unsigned char w;
unsigned char z[ 2 ];
} example_struct;

example_struct ex_s;
unsigned char array[ <some val-could be several thousand> ];

I looked at this question: Convert a struct to vector of bytes and I wrote the following:

std::vector< unsigned char > v( sizeof( example_struct ) + array_len );
unsigned char * ptr = reinterpret_cast< unsigned char * >( &ex_s );
std::vector< unsigned char > tmp_v( ptr, ptr + sizeof( example_struct ) );
v = tmp_v;
std::vector< unsigned char > tmp_v2( array, array + array_len );
v.insert( v.end(), tmp_v2.begin(), tmp_v2.end() );

Is there an easier ( more readable ) way to do it?

Would it be more efficient to create v with the contents of the structure rather than assigning the temporary variable to it?

If that is done, then v wouldn't be the size of the final length most likely resulting in another memory allocation via the vector when the array is added. Would an empty vector creation followed by a reserve of the total length plus the additions be preferred?

Is swap preferred over assignment?

Is insert the preferred way to add the 2nd vector?

Any other recommendation on how you'd write this?

Community
  • 1
  • 1
  • 1
    This question is too broad for Stack Overflow, which is for specific questions about coding with definite answers. This is more more appropriate for [Code Review](http://codereview.stackexchange.com) or [Programmers](http://programmers.stackexchange.com). Please read [this meta post](http://meta.stackexchange.com/a/82990/228805) for more information. – Adi Inbar Mar 04 '14 at 23:48

1 Answers1

0

You don't need to create a temporary vector, you can just use insert(), e.g.:

vector<unsigned char> v;
unsigned char *ptr = (unsigned char *)&ex_s;
v.insert(v.end(), ptr, ptr + sizeof(example_struct));
v.insert(v.end(), array, array + array_len);

Note that you also don't need (or, in the case of my example, want) to give the vector an initial size. However, you may wish to reserve capacity ahead of time (an easy, if sometimes premature, optimization):

v.reserve(sizeof(example_struct) + array_len); // <- prior to inserts

Also, please note that structure member padding will likely cause its representation in the vector to not be what you expect; or at minimum to be inconsistent across compilers. You will want to use 1-byte packing; a compiler specific option (e.g. #pragma pack for MSVC or __attribute__((packed)) for GCC). Otherwise you will likely have junk padding bytes between structure members.

A truly portable approach would be to insert each member, by value, one at a time, and use bitwise operations on the shorts to enforce endianness, and not convert pointers around or do byte copies.

Jason C
  • 38,729
  • 14
  • 126
  • 182
  • But of course! That makes so much sense. Thanks. – Grasshopper Mar 04 '14 at 21:58
  • @Grasshopper BTW you don't really have to use `reinterpret_cast` for this particular case, but it *does* very clearly indicate your intentions, so, don't take my snippet as a case against it. – Jason C Mar 04 '14 at 22:00