2015-04-17 120 views
1

我有我想用双打的数组转换为双打的载体的功能:的memcpy转换阵列矢量

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 

为什么?

回答

6

你的问题的memcpy预计字节大小,而不是数量的元素,所以你需要乘上第三但实际上你应该做的是使用向量的构造函数,期望两个迭代器如下所示:

std::vector<double> y(x, x + 3); 

这种方式,你甚至都不需要担心的sizeof和它的短!

另外,您可以使用std::copy(在我的评论中提到/对方的回答但是这不再毫无理由地)

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; 
} 
+5

或者更好的std ::复制,甚至更好的初始化向量与两个迭代器(即改编和编曲+长度) – Borgleader

+1

@Borgleader,这真的是唯一的答案在这里。它首先否定了对“ArrayToVector”的需求。甚至比调用函数需要更少的代码字符。 – chris

2

不要使用memcpy复制到std::vector,效率较低,而且容易出错。

这是因为当构造或调整矢量它填补与值初始化元件新元素(除非提供一个),其为算术类型是0效率较低。但是这样的初始化是不必要的,因为你会覆盖这些值。初始化可能很便宜,但它不是免费的。

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

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


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

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

而一个C++编译器知道从类型的对准和尺寸和内联产生适当的SIMD指令没有这些对准和尺寸检查该C库函数做。再次,这些支票可能便宜,但它们不是免费的。

C++等std::copystd::copy_backwardstd::fill和容器复印功能算法,它采取两个迭代自动使用使用这些C原语功能POD类型。

对于你来说,C++初始化表达式如{}double buf[N] = {};中做memset,但是同样以更高效和更不容易出错的方式。

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用于分配的阵列。