c++arraysmemcpy

How do I copy a unsigned long long to a byte array in c++?


I have code that sets each byte of a byte array m individually from an unsigned long long named i. I want to do it in ONE operation using memcpy. So copy the value of i to m, so that each byte of m, from index 4 to 11, corresponds with a byte from i, which, as an unsigned long long, is eight bytes. So copy each byte from i to m, so that m[4] = first byte of i, m[5] = second byte of i, etc.

I tested this code in the context of some other code, and it is fast. But I want to use memcpy instead of individual assignments to also test the speed of that.

So here is the code:

int thread = blockIdx.x * blockDim.x + threadIdx.x + 0xeafe7436;
uchar m[12];
uint res[4];
m[0] = (uchar)(thread & 0x000000ff);
m[1] = (uchar)((thread >> 8) & 0x000000ff);
m[2] = (uchar)((thread >> 16) & 0x000000ff);
m[3] = (uchar)((thread >> 24) & 0x000000ff);

for (unsigned long long i = 0; i < 0xffffffffffffffff; i++) {
    m[4] = (uchar)(i & 0x00000000000000ff);
    m[5] = (uchar)((i >> 8) & 0x00000000000000ff);
    m[6] = (uchar)((i >> 16) & 0x00000000000000ff);
    m[7] = (uchar)((i >> 24) & 0x00000000000000ff);
    m[8] = (uchar)((i >> 32) & 0x00000000000000ff);
    m[9] = (uchar)((i >> 40) & 0x00000000000000ff);
    m[10] = (uchar)((i >> 48) & 0x00000000000000ff);
    m[11] = (uchar)((i >> 56) & 0x00000000000000ff);
    md5(m, 12, res);
}

The shifting and bitwise operations, I think, make my code slower then it should be, so I wanted to try to use memcpy to see if that is faster.

I want to copy the value of i to m, sarting at index 4. How would I do this using memcpy? I have looked into other questions but found them confusing and hard to understand and could not do it myself.


Solution

  • You're overthinking this. Understand that unsigned long long and byte array are just essentially memory locations. All you want/need to do is copy the data from one to the other. And then potentially catching endianness issues.

    int main() 
    {
        unsigned long long value = 0xeafe7436;
    
        uint8_t m[sizeof(unsigned long long)];
        uint32_t res[sizeof(unsigned long long) / sizeof(uint32_t)] = {};
    
        std::memcpy(m, &value, sizeof(value));
        std::memcpy(res, &value, sizeof(value));
    
        // This will reverse the byte order to match the original endianness
        // Discard if not needed.
        // If you're using C or C++ older than 17, you'll need to byte swap with a 
        // for loop
        std::reverse(m, m + sizeof(m));
        
        std::cout << "value: " << std::hex << value;
    
        std::cout << "\n m Array: ";
        for (size_t i = 0; i < sizeof(m); ++i) 
            std::cout << std::hex << static_cast<int>(m[i]) << " ";
    
        std::cout << "\n res Array: ";
        for (size_t i = 0; i < sizeof(res) / sizeof(uint32_t); ++i) 
            std::cout << std::hex << res[i] << " ";
    
        return 0;
    }
    
    value: eafe7436
    m Array: 0 0 0 0 ea fe 74 36
    res Array: eafe7436 0