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];
source to share
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);
source to share
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
).
source to share