错误使用 std::copy? [英] Wrong use of std::copy?

查看:39
本文介绍了错误使用 std::copy?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

#include #include #include #include <向量>使用命名空间标准;typedef unsigned char 字节;int main(){uint32_t ui32 = 12;size_t sizeofUi32 = sizeof ui32;cout<<sizeofUi32:"<<sizeofUi32<<结束;向量<字节>v(10);std::copy(&ui32, &ui32 + sizeof ui32, &v[4]);uint32_t 结果 = 0;std::copy(&v[4], &v[4] + sizeof ui32, &result);cout<<结果:"<<结果<<" sizeofUi32: " <<sizeofUi32<<结束;返回0;}

输出:

sizeofUi32: 4结果:12 sizeofUi32:17179869184

我认为这个问题可能是由于 std::copy 接受迭代器而不是指针,而是由于我在 SO 这里,

<块引用>

指针是迭代器

所以我的示例代码肯定有一个简单的问题,我遗漏了.但我看不出来.你能解释一下,这里有什么问题吗?

编辑 1:

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

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

解决方案

眼前的问题在这里:

<块引用>

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

&ui32 具有 uint32_t * 类型,并且添加任何内容已经考虑了对象的大小.您正在有效地尝试复制 sizeof ui32 uint32_t 对象,但您只有一个,因此您应该使用 + 1.

除此之外,对不同类型的指针使用 std::copy 可能不会给您预期的结果.它具有 v[4] = ui32; 的效果,只要 ui32Byte 的范围内,它就起作用,它是在这里,但一般来说这不是您可以依赖的.

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

你可以做的是:

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

Here is a simple test program that illustrates the problem I faced:

#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 issue might be due to std::copy accepting iterators not pointers, but from what I got in SO here,

a pointer IS an iterator

So there must be a simple issue with my sample code, that I' missing. But I can't spot it. Could you please explain, what's wrong here?

EDIT 1:

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

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

解决方案

The immediate problem is here:

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

&ui32 has type uint32_t *, and adding anything to that already takes into account the object's size. You're effectively attempting to copy sizeof ui32 uint32_t objects, but you only have a single one, so you should be using + 1.

That aside, using std::copy with pointers of different types is likely not to give you the results you expect. It has the effect of v[4] = ui32;, which works as long as ui32 is inside Byte's range, which it is here, but that's not something you can rely on in general.

The second std::copy has roughly the same problem, but in the opposite direction.

What you could do is:

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

这篇关于错误使用 std::copy?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆