繁体   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