簡體   English   中英

Memcpy用於將數組轉換為向量

[英]Memcpy for converting array to vector

我有一個函數要用於將雙精度數組轉換為雙精度向量:

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

為什么?

您的問題是memcpy期望以字節為單位的大小,而不是元素的數目,因此您需要將第三個參數乘以sizeof(double)但實際上您應該做的是使用vector的構造函數,它需要兩個迭代器,如下所示:

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

這樣,您甚至不必擔心sizeof,而且它更短!

或者,您可以使用std::copy (如我的評論/其他答案中所述,但這更長的時間沒有理由)

您需要使用:

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

不要使用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庫函數所做的那些對齊方式和大小檢查。 同樣,這些支票可能很便宜,但不是免費的。

std::copy_backward兩個迭代器的std::copystd::copy_backwardstd::fill和容器復制等C ++算法會自動將這些C原語函數用於POD類型。

C ++初始值設定項表達式,例如{}double buf[N] = {}; 再為您做一次memset設置,但是又可以更高效,更不易出錯。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM