c++memcpy

Replacing reinterpret_cast by memcpy


I've got some legacy code containing the following line of code:

uint16_t* data = reinterpret_cast<uint16_t*>(array_.data()); // #1

With array_ of type std::vector. So far, I understood that we store into data a pointer to the first element of the vector, and we tell the compiler to consider it as an uint16_t.

For some reasons, I'm looking to replace the reinterpret_cast by a memcpy.

I've come along with the following replacement lines:

uint16_t* data;
memcpy(&data, typed_array_.data(), bytes_per_elem); // #2

With bytes_per_elem the size in bytes of vector elements.

I'm not very fluent with the use of reinterpret_cast and memcpy, so I'd like to know, can I consider #1 and #2 as equivalent?


Solution

  • can i consider #1 and #2 as equivalent ?

    No, the #2 code looks very invalid. It tries to interpret the data stored in a vector as a pointer value to uint16_t. Which the first interprets the data stored in the vector as values of uint16_t, not a pointer value.

    I guess you probably meant to allocate the memory to store the actual data:

    // assuming std::vector<uint8_t> array_;
    std::vector<uint16_t> data(array_.size() / sizeof(uint16_t));
    memcpy(data.data(), array_.data(), array_.size());
    

    But it would be much better to do the actual conversion, like:

    // assuming std::vector<uint8_t> array_;
    std::vector<uint16_t> data(array_.size() / sizeof(uint16_t));
    for (size_t i = 0; i < array_.size(); i += 2) {
        // little endian or big endian?
        data[i / 2] = array_[i] << 8 | array_[i + 1];
    }
    

    Consider researching strict aliasing rules, reinterpret_cast, how does pointers differ from values, what is & operator in C++, <bit>, std::byte, std::bit_cast.