2014-12-21 56 views
3

下面是一个简单的测试程序,它说明了我所面临的问题:错误地使用std :: copy?

#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; 
} 

输出:

sizeofUi32: 4  
Result: 12 sizeofUi32: 17179869184 

我想这个问题可能是由于到std ::复制接受迭代器不是指针,而是从我在SO here了,

的指针是一个迭代

所以我的示例代码必须有一个简单的问题,我错过了。但我无法发现它。 你能解释一下,这里有什么问题吗?

编辑1:

从我上心的答案,即反序列化的字节向量,如果我知道正确的顺序和类型在矢量存储的数据的,我能避免使用std

所以: :复制并将矢量值分配给适当类型的变量。它有效,但安全吗?

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

您可能想使用'std :: copy_n' –

+0

@AlexandreC。,对!感谢您的提示 – rightaway717

回答

8

眼前的问题是在这里:

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

&ui32的类型为uint32_t *,并添加任何东西已经考虑到对象的大小。您有效尝试复制sizeof ui32uint32_t对象,但您只有一个对象,因此您应该使用+ 1

另外,使用std::copy指针不同类型可能不会给你你期望的结果。它的效果是v[4] = ui32;,只要ui32位于Byte的范围内,它就在这里,但这通常不是你可以依赖的。

第二个std::copy有大致相同的问题,但方向相反。

你可以做的是:

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); 
+0

因此,从我的答案中,我需要将'std :: copy'中使用的指针转换为相同类型以实现所需的结果,对吧? – rightaway717

+0

@ rightaway717不只是相同的类型,特别是'Byte *'('unsigned char *')。如果尝试转换其他方法,如果尝试对所有三个参数使用'uint32_t *',则可能会发现'&v [4]'不适合对齐。 – hvd

3

的问题是不是与std::copy但指针运算。正如你所说的,“指针是一个迭代器”。但更重要的是,这是强类型。因此,指向uint32_t的指针与指向unsigned char的指针不同。

添加&ui32 + sizeof ui32有效地将ui32看作好像它是具有4个元素(类型uint32_t)的连续数组的开始。