【问题标题】:Constructing Eigen::Array from Eigen::Map, how does it work?从 Eigen::Map 构造 Eigen::Array,它是如何工作的?
【发布时间】:2019-12-26 02:17:49
【问题描述】:

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

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中的数据而不是复制它,并在销毁时释放这块内存,我该如何实现?在here,我注意到Eigen::ArrayEigen::Matrix 可以用原始数据指针初始化,但它似乎只适用于固定大小的数组和矩阵。这个函数会被频繁调用,所以我很关心效率。

【问题讨论】:

    标签: c++ eigen eigen3


    【解决方案1】:

    ArrayXf 有一个来自Map&lt;ArrayXf&gt; 的隐式构造函数(实际上来自任何ArrayBase&lt;...&gt; 对象),它可以对内容进行深层复制。 从 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 作为成员函数的类的成员变量)。

    【讨论】:

    • 谢谢,非常有帮助。 C++确实很复杂,即使你很了解语言核心机制,但最佳实践有时仍然不容易弄清楚。先分配然后查看它然后按值返回是一个好主意。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-23
    • 2015-12-10
    相关资源
    最近更新 更多