2015-04-17 58 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用於分配的陣列。