用于将数组转换为向量的Memcpy

时间:2015-04-17 20:35:51

标签: c++

我有一个函数,我想用它来将双精度数组转换为双精度数:

std::vector<double> ArrayToVector(const double* arr, int length)
{
    std::vector<double> vec(length);
    memcpy(&vec[0], &arr[0], length);
    return vec;
};

但是当我跑步时:

int main()
{
    double* x = new double[3];
    x[0] = 2;
    x[1] = 4;
    x[2] = 6;
    std::vector<double> y = ArrayToVector(x, 3);
    for (int i = 0; i < 3; i++)
    {
        std::cout << y[i] << " ";
    }

    return 0;
}

我得到了输出:

0 0 0

而不是

2 4 6

为什么?

4 个答案:

答案 0 :(得分:6)

你的问题是memcpy期望一个字节大小,而不是元素数,所以你需要将第三个参数乘以sizeof(double),但实际上你应该做的是使用vector的构造函数,它需要两个迭代器,如此:

std::vector<double> y(x, x + 3);
这样你就不用担心尺寸而且它更短了!

或者您也可以使用std::copy(如我的评论/其他答案中所述,但无缘无故更长)

答案 1 :(得分:2)

您需要使用:

memcpy(&vec[0], &arr[0], length*sizeof(double));

或者更好,使用:

int main()
{
    double* x = new double[3];
    x[0] = 2;
    x[1] = 4;
    x[2] = 6;

    std::vector<double> y(x, x+3);    
    for (int i = 0; i < 3; i++)
    {
        std::cout << y[i] << " ";
    }

    return 0;
}

答案 2 :(得分:2)

请勿使用memcpy复制到std::vector,效率低且容易出错。

效率较低,因为在构造或调整向量时,它会使用值初始化元素(除非您提供一个元素)填充新元素,对于算术类型,该元素为0。但是,初始化是不必要的,因为您随后会覆盖这些值。初始化可能很便宜,但它不是免费的。

std::vector有一个构造函数,它接受两个迭代器,正如其他人已经提到的那样,复制输入范围。这个构造函数避免了在复制之前不必要的默认初始化。

std::vector还有assigninsert个成员函数,它们接收两个迭代器并有效地复制输入范围。 v.append(beg, end)v.insert(v.end(), beg, end)


在我看来,在C ++代码中使用memsetmemcpymemmov始终是一个错误。

这些函数由标准C库实现,因此丢失输入参数类型/对齐信息(因为它们采用void*)。在切换到最合适的SIMD版本之前,他们需要在运行时检查参数的对齐和大小。未对齐的开头和结尾由非SIMD指令处理。

虽然C ++编译器知道类型的对齐和大小,但是内联生成适当的SIMD指令,而没有C库函数所做的那些对齐和大小检查。同样,这些检查可能很便宜,但它们不是免费的。

C ++算法(如std::copystd::copy_backwardstd::fill和带有两个迭代器的容器复制函数会自动将这些C原语函数用于POD类型。

{}中的double buf[N] = {};等C ++初始化表达式为您做memset,但同样,更高效,更不容易出错。

答案 3 :(得分:1)

memcpy复制字节。因此,您必须指定要复制的字节数(而不是双精度数)。

memcpy(&vec[0], &arr[0], length * sizeof( double ) );

然而这种方法很糟糕。最好按以下方式定义矢量

std::vector<double> ArrayToVector(const double* arr, int length)
{
    return { arr, arr + length };
}

或者

std::vector<double> ArrayToVector(const double* arr, int length)
{
    std::vector<double> vec( arr, arr + length );
    return vec;
}

考虑到您需要为阵列释放已分配的内存。您可以使用智能指针std::unique_ptr作为已分配的数组。