错误地使用std :: copy?

时间:2014-12-21 14:23:57

标签: c++ std

这是一个简单的测试程序,说明了我遇到的问题:

#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 :: copy接受迭代器而不是指针,而是因为我在SO here中得到的,

  

指针是迭代器

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

编辑1:

所以从答案我得到了想法,即反序列化字节向量,如果我知道向量中存储数据的正确顺序和类型,我可以避免使用std :: copy并将向量值分配给变量适当的类型。它有效,但是安全吗?

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

2 个答案:

答案 0 :(得分:8)

当前存在的问题是:

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

&ui32的类型为uint32_t *,并且已添加任何内容已考虑到对象的大小。您有效地尝试复制sizeof ui32 uint32_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); 有大致相同的问题,但方向相反。

你能做的是:

{{1}}

答案 1 :(得分:3)

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

添加&ui32 + sizeof ui32有效地将ui32视为具有4个元素(类型为uint32_t)的连续数组的开头。