簡體   English   中英

如何在C ++中將2d向量轉換為1d數組?

[英]How convert 2d vector to 1d array in C++?

我需要能夠在不使用C ++智能指針的情況下做到這一點。 我嘗試了以下

double* VecToArr(std::vector<std::vector<double>> vec) {
    double* newarr=new double(vec.size());
    for (int i=0; i<vec.size(); i++) {
        std::copy(vec[i].begin(), vec[i].end(), newarr);
        newarr += vec[i].size();
    }
    std::cout<<"inside \n";
    for (int i=0; i<vec.size(); i++) {
        std::cout<<newarr[i]<<"\n";
    }
    return newarr;
}

int main(){
    std::vector<double> x{1,2};
    std::vector<double> y{3,4};
    std::vector<std::vector<double>>vec;
    vec.push_back(x);
    vec.push_back(y);
    double *arr=VecToArr(vec);
    std::cout<<"outside \n";
    for (int i=0; i<4; i++) {
        std::cout<<arr[i]<<"\n";
    }
}

但是在VecToArr內部,輸出為:

inside
4.54e-322 2.18e-317 4.34e-311 4.24e-314

不是我預期的1 2 3 4

在它外面,我得到相同的垃圾值。 為什么是這樣?

此外,由於我用new創建newarrVecToArr ,在那里我怎么delete呢? main.cpp ,在打印出值之后,是否只delete arr[]

編輯

當我將功能更改為:

double* VecToArr(std::vector<std::vector<double>> vec) {
    double* newarr=new double[vec.size()*vec[0].size()];
    for (int i=0; i<vec.size(); i++) {
        std::copy(vec[i].begin(), vec[i].end(), newarr);
        newarr += vec[i].size();
    }
    std::cout<<"inside \n";
    for (int i=0; i<vec.size(); i++) {
        std::cout<<newarr[i]<<"\n";
    }
    return newarr;
}

現在的輸出是3 4 (garbage) (garbage)而不是1 2 3 4

正如其他人在評論中提到的那樣,這三個主要問題還有更多。 首先,您使用了錯誤的新表達式類型, new double(...)只是為單個double分配了內存,並使用提供的值對其進行了初始化。 您可能希望new double[...]分配一個new double[...]數組。

其次,提供給此新控件的大小不正確,僅代表向量的第一維(當它需要為所有嵌套向量大小的總和時)。

最后,您將返回newarr ,該值已由函數內的for循環修改,並最終在分配發生后指向內存,您可能希望在開始時進行臨時復制並返回相反。

經過所有更改,最終的正確功能可能如下所示:

double* VecToArr(std::vector<std::vector<double>> vec) {
    std::size_t totalsize = 0;

    for (int i=0; i<vec.size(); i++) {
        totalsize += vec[i].size();
    }

    double* newarr=new double[totalsize];
    double* walkarr=newarr;

    for (int i=0; i<vec.size(); i++) {
        std::copy(vec[i].begin(), vec[i].end(), walkarr);
        walkarr += vec[i].size();
    }

    return newarr;
}

我還建議通過常量引用傳遞向量,因為當前(按當前)通過值傳遞向量,這沒有任何理由,這可能會導致不必要的開銷。 另外,您應該嘗試始終使用std::vector類的東西(或至少是智能指針)來分配內存,而不要直接使用new / delete (除非處理底層容器實現),因為通常沒有太多理由打開程序導致內存泄漏的代價。

看一下這段代碼:

double* newarr=new double[vec.size()];
for (int i=0; i<vec.size(); i++) {
    std::copy(vec[i].begin(), vec[i].end(), newarr);
    newarr += vec[i].size();
}

這里違反了一個簡單的數學邏輯。 您將newarr分配為vec的大小。 到現在為止還挺好。 現在,對於vec每個元素,您都將指針增加vec[i].size有效地導致使用的SUM(vec[i].size()) 這是不對的,通過訪問超出分配范圍的數組,您在程序中有未定義的行為。

請注意,我還修復了您的代碼中的錯字-您的new double(vec.size())原始版本分配了一個double,而不是一個array。

內存分配,索引編制和指針算法存在問題。 我已經在您的代碼中指出了這些。

#include <iostream>
#include <vector>

double* VecToArr(const std::vector<std::vector<double>>& vec) {
    double* newarr=new double[vec.size() * vec[0].size()]; // <-- you have 4 elements (also notice square brackets)
    double* newarr_ptr_copy = newarr;
    for (int i=0; i<vec.size(); i++) {
        std::copy(vec[i].begin(), vec[i].end(), newarr_ptr_copy);
        newarr_ptr_copy += vec[i].size(); // don't lose track of newarr
    }

    std::cout<<"inside \n";
    for (int i=0; i<vec.size(); i++) {
        std::cout<<newarr[i]<<"\n";
    }
    return newarr;
}

int main(){
    std::vector<double> x{1,2};
    std::vector<double> y{3,4};
    std::vector<std::vector<double>>vec;
    vec.push_back(x);
    vec.push_back(y);
    double *arr=VecToArr(vec);
    std::cout<<"outside \n";
    for (int i=0; i<4; i++) {
        std::cout<<arr[i]<<"\n";
    }
    delete [] arr; // make sure that you release the memory that you allocated
}

暫無
暫無

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

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