删除矢量而不删除数组

时间:2017-04-05 19:58:33

标签: c++ pointers stdvector

我正在尝试在C ++中填充双向量,并将关联的数组传递给Fortran。但是我无法释放与向量相关的其余内存。我想避免复制。这就是我所拥有的:

std::vector<double> *vec = new std::vector<double>();
(*vec).push_back(1.0);
(*vec).push_back(2.0);
*arr = (*vec).data();            //arr goes to Fortran

如何在保持vec完整的同时删除arr?有没有办法在arr中取消指向vec的指针,以便我可以删除vec

更新

我看到我在这里没有提供足够的信息。几件事:

  1. 我实际上是在使用iso_c_binding
  2. 在Fortran中调用C ++函数
  3. 我不知道vec需要多大。向量类看起来很适合这种情况
  4. 我最终可能会尝试Guillaume的建议,但是现在,我正在将vec传递给Fortran,并在我完成数据后调用另一个C ++函数来删除它

4 个答案:

答案 0 :(得分:3)

您需要重新考虑您的计划设计。

不知何故,在某些地方,当Fortran使用它时,你需要保持一个数组存活。因此,无论您使用什么上下文来访问Fortran都应该负责此阵列的所有权。

class fortran_context {
    /*Blah blah blah whatever API you're using to access Fortran*/
    void * arr;
    std::vector<double> vec; //Don't allocate this as a pointer; makes no sense!
public:
    fortran_context() {
        arr = //Do whatever is necessary to setup Fortran stuff. I'm assuming your
        //api has some kind of "get_array_pointer" function that you'll use.
    }

    ~fortran_context() {
        //Do the cleanup for the fortran stuff
    }

    //If you want to spend time figuring out a robust copy constructor, you may.
    //Personally, I suspect it's better to just delete it, and make this object non-copyable.
    fortran_context(fortran_context const&) = delete;

    std::vector<double> & get_vector() {
        return vec;
    }

    std::vector<double> const& get_vector() const {
        return vec;
    }

    void assign_vector_to_array() {
        *arr = vec.data();
    }

    void do_stuff_with_fortran() {
        assign_vector_to_array();
        //???
    }
};

int main() {
    fortran_context context;
    auto & vec = context.get_vector();
    vec.push_back(1.0);
    vec.push_back(2.0);
    context.do_stuff_with_fortran();
    return 0;
} //Cleanup happens automatically due to correct implementation of ~fortran_context()

我已经抽象了很多,因为我不知道你使用什么API来访问Fortran,而且我不知道你做了什么样的工作用这个数组做。但到目前为止,这是确保

最安全的方法
  • 只要你在Fortran中做事,
  • 就会存在向量的分配内存
  • 完成后,与矢量关联的内存将被正确清理。

答案 1 :(得分:1)

  

如何在保持arr完整的同时删除vec?有没有办法在vec中取消指向arr的指针,以便我可以删除vec?

该库不提供任何内置功能。你必须自己做簿记工作。

  1. 为数据分配内存并从向量中复制数据。
  2. 将数据发送到FORTRAN。
  3. 决定何时可以安全地取消分配数据,然后将其删除。
  4. // Fill up data in vec
    std::vector<double> vec;
    vec.push_back(1.0);
    vec.push_back(2.0);
    
    // Allocate memory for arr and copy the data from vec
    double* arr = new double[vec.size()];
    std::copy(vec.begin(), vec.end(), arr);
    
    // use arr
    
    // delete arr
    delete [] arr;
    

答案 2 :(得分:0)

你要求的是不可能的。 std :: vector,作为一个表现良好的模板类,将释放它所拥有的内部构件并在其被销毁时进行管理。

在使用其内容时,您必须保持矢量活着,这非常有意义。否则,你将不得不复制。

另外,我不明白为什么要在堆上分配向量,它似乎根本不需要。

答案 3 :(得分:-1)

  

如何在保持arr完整的同时删除vec?有没有办法在vec中取消指向arr的指针,以便我可以删除vec?

你没有。

我认为你滥用或误解了什么是矢量。它并不是要公开底层数组的内存管理,而是将动态大小的数组表示为常规类型。

如果您需要明确管理内存,我建议您使用std::unique_ptr<T[]>。由于唯一指针提供了一种管理内存并在不删除内存的情况下释放资源的方法,因此我认为它是满足您需求的理想选择。

auto arr = std::make_unique<double[]>(2);
arr[0] = 1.;
arr[1] = 2.;
auto data = arr.release();

// You have to manage `data` memory manually,
// since the unique pointer released it's resource.

// arr is null here
// data is a pointer to an array, must be deleted manually later.

delete[] data;