首页 > 解决方案 > 从 Eigen::Map 构造 Eigen::Array,它是如何工作的?

问题描述

在我的项目中,我编写了以下代码:

Eigen::ArrayXf foo(const Eigen::ArrayXcf &src)
{
    auto * output = new float[src.size()];
    //Fill the data here
    return Eigen::Map<Eigen::ArrayXf>(output, src.size());
}

请注意,在 return 语句中构造的东西是Eigen::Map,但编译器不会抱怨任何东西,因此必须进行转换。因此,我有以下问题:

  1. 这种转换是如何发生的?通过制作原始数据的深层副本或只是更改所有权?
  2. 这段代码可以吗?它会导致未定义的行为或内存泄漏吗?
  3. 如果我希望返回的Eigen::Array拥有数据*output而不是复制它,并在销毁时释放这块内存,我该如何实现呢?在这里我注意到Eigen::Array并且Eigen::Matrix可以使用原始数据指针进行初始化,但它似乎只适用于固定大小的数组和矩阵。这个函数会被频繁调用,所以我很关心效率。

标签: c++eigeneigen3

解决方案


ArrayXfMap<ArrayXf>有一个来自(实际上来自任何对象)的隐式构造函数,ArrayBase<...>它对内容进行深层复制。从 Eigen 的角度来看,您的代码是安全的,但是您会泄漏内存,因为您永远不会取消分配float* output数据。通常,new在编写干净的 C++ 代码时应该避免或至少封装。

您可以通过直接分配Array稍后要返回的对象来简化代码(由于 RVO(返回值优化),在任何非古代 C++ 编译器上都不会有副本):

Eigen::ArrayXf foo(const Eigen::ArrayXcf &src)
{
    Eigen::ArrayXf output_array(src.size());
    float * output = output_array.data();
    //Fill the data here
    return output_array;
}

如果要完全避免内存分配(在函数内部),则需要详细说明实际分配内存的位置。您可以Array在该位置构造一个对象并通过引用您的函数将其传递(或使其成为具有foo作为成员函数的类的成员变量)。


推荐阅读