1

I would like to convert std::uint32 to std::vector<std::uint8> in a better way than this:

std::uint32_t base_rva = 0xccddee00;
std::vector<std::uint8_t> vraw_data;

//copying base_rva to raw_data
vraw_data.resize(sizeof(base_rva));
std::memcpy(vraw_data.data(), &base_rva, sizeof(base_rva)); 

I was looking for something like:

std::vector<std::uint8_t> vraw_data((std::uint8_t*)&base_rva, sizeof(base_rva));

Any suggestions?

2 Answers2

5

I was looking for something like:

std::vector<std::uint8_t> raw_data((std::uint8_t*)&base_rva, sizeof(base_rva));

There's no such constructor available for std::vector, but supposed you want to store the copy of a std::uint32_t internal representation in a std::vector<std::uint8_t> you can simply do

 std::uint32_t data = 42;
 std::vector<std::uint8_t> raw_data( (std::uint8_t*)&data
                                   , (std::uint8_t*)&(data) + sizeof(std::uint32_t));

according (4) from std::vector constructors.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • It works! Thank you! The task is all about transforming a std::uint32_t in a way that exactly it looks in memory(liltle endian x86 intel) – Francisco Gomes Jul 04 '16 at 21:18
  • Technically this would break strict aliasing rule if `uint8_t` is not an alias for [unsigned] char. – Revolver_Ocelot Jul 04 '16 at 21:22
  • @Revolver_Ocelot very interested on this, can you link me with some information? Isn't std::uint8_t an alias to unsigned char? – Francisco Gomes Jul 04 '16 at 21:30
  • @FranciscoGomes Well, it's unlikely that `std::uint8_t` isn't actually a `typedef uinsigned char uint8_t;` but you might well simply replace `std::uint8_t` with `unsigned char`. – πάντα ῥεῖ Jul 04 '16 at 21:34
  • @FranciscoGomes C++ states that [accessing object through pointer of incompatible type is UB](http://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule). Signed/unsigned and usual `char` pointer is compatible with anything. Fixed width types are not required to alias any specific type: they can in theory be an alias to some compiler intrinsic type (however it is unlikely). – Revolver_Ocelot Jul 04 '16 at 21:35
  • thanks for reminding me, really valuable information here, thanks! – Francisco Gomes Jul 04 '16 at 22:10
  • Seems the parenthesis don't match? one more close parenthesis in the end? – Yang Xu Mar 30 '21 at 17:53
  • also, seems it is no longer (4) in [std::vector constructors](https://en.cppreference.com/w/cpp/container/vector/vector). but (5). – Yang Xu Jul 26 '21 at 15:35
0

If you don't like casting, you could do it like...

union to_byte_vector
{
  uint32_t val;
  uint8_t bytes[1];

  to_byte_vector() = default;
  to_byte_vector(uint32_t v) : val(v) {}
  to_byte_vector(const to_byte_vector& o) : val(o.val) {}
  to_byte_vector& operator=(const to_byte_vector& o) { val = o.val; return *this; }
  operator uint32_t() const { return val; }
  std::vector<uint8_t> get_vector() const { return std::vector<uint8_t>(begin(), end()); }

private:
  const uint8_t* begin() const { return bytes; }
  const uint8_t* end() const { return bytes + sizeof(uint32_t); }
};

And use it like...

auto vec = to_byte_vector(42).get_vector();

But really, this is just letting the union do the casting work for you.

evan
  • 1,463
  • 1
  • 10
  • 13