Incorrect use of std :: copy?

Here's a simple test program that illustrates the problem I'm facing:

#include <iostream>
#include <stdlib.h>
#include <inttypes.h>
#include <vector>

using namespace std;
typedef unsigned char Byte;

int main( )
{
    uint32_t ui32 = 12;
    size_t sizeofUi32 = sizeof ui32;
    cout << "sizeofUi32: " << sizeofUi32 << endl;
    vector<Byte> v(10);
    std::copy(&ui32, &ui32 + sizeof ui32, &v[4]);

    uint32_t result = 0;
    std::copy(&v[4], &v[4] + sizeof ui32, &result);

    cout << "Result: " << result << " sizeofUi32: " << sizeofUi32 << endl;

    return 0;
}

      

output:

sizeofUi32: 4    
Result: 12 sizeofUi32: 17179869184

      

I thought this problem might be caused by std :: copy accepting iterators not pointers, but from what I got on SO here ,

pointer IS iterator

So there should be a simple question with my sample code that I can't see. But I cannot see it. Can you explain what is wrong here?

EDIT 1:

So, from the answers, I figured out that to deserialize a vector of bytes, if I know the correct order and types of stored data in the vector, I can avoid using std :: copy and just assign the vector values ​​to the variables with the correct types. It works, but is it safe?

uint32_t a = v[4];
uint8_t b = v[8];

      

+3


source to share


2 answers


The immediate problem is here:

std::copy(&ui32, &ui32 + sizeof ui32, &v[4]);
                       ^^^^^^^^^^^^^

      

&ui32

has a type uint32_t *

, and adding something to that already takes into account the size of the object. You are trying to copy objects sizeof ui32

uint32_t

, but you only have one, so you must use + 1

.

As an aside, using std::copy

with different types of pointers will likely not give you the results you expect. It acts v[4] = ui32;

that works as long as it ui32

is within the range Byte

that it is here, but it is not something you can rely on at all.



The second std::copy

has about the same problem, but in the opposite direction.

What can you do:

std::copy((Byte*) &ui32, (Byte*) (&ui32 + 1), &v[4]);
// or std::copy((Byte*) &ui32, (Byte*) &ui32 + sizeof ui32, &v[4]);
...
std::copy(&v[4], &v[4] + sizeof ui32, (Byte*) &result);

      

+8


source


The problem is not with std::copy

, but with pointer arithmetic. As you said, "pointer is an iterator". But more importantly, he was heavily recruited. Thus, a pointer to uint32_t

is different from a pointer to unsigned char

.



The append &ui32 + sizeof ui32

effectively treats ui32

as if it were the start of a contiguous 4-element array (of type uint32_t

).

+3


source







All Articles