是否在堆上自动创建了特征矩阵?

问题描述 投票:0回答:3

这个问题可能很愚蠢,但我是初学者。 当我在本地范围内创建 Eigen::MatrixXd 时,如下所示:

    void foo(){
        Eigen::MatrixXd m(rows,cols);
        // do stuff
    }

对象会在堆上还是在栈上? 我希望它在堆栈上,因为我不使用“new”关键字。

c++ matrix memory eigen
3个回答
9
投票

Eigen::Matrix
的特化实例可以存储在堆或栈上

正如接受的答案中提到的,

m
具有自动存储期限。然而,重要的是要指出,随后的声明

当然,

Eigen::MatrixXd
将动态管理其大部分内部内存,但您不需要关心这一点。

一般来说,

不适用于

Eigen::Matrix
的专门化实例,并且还需要指出的是,这确实是您可能想要关心的事情,特别是如果在不允许动态内存的环境中工作(例如,嵌入式环境)。

动态大小的
Eigen
矩阵

您正在使用动态大小的矩阵(重点放在

X
中的
Eigen::MatrixXd
。任何
Eigen::MatrixX...
类型都只是
Eigen::Matrix< ..., Dynamic , Dynamic >
的 typedef,其中
Dynamic
表示其大小为编译时未知:

const int Eigen::Dynamic

该值意味着在编译时未知的正数(例如大小),而是该值存储在某个运行时变量中。

Eigen::Matrix
的特征文档(所有
Eigen::MatrixX...
都是其特化)明确表示动态大小矩阵的数据将存储在堆上[强调我的]:

固定大小与动态大小:

固定大小意味着行数和列数已知 编译时。在这种情况下,Eigen 分配数组 系数作为固定大小的数组,作为类成员。 ...

动态大小意味着行数或列数不变化 在编译时必然已知。在这种情况下,它们是运行时的 变量,并且系数数组 动态分配 堆

固定大小的
Eigen
矩阵

从上面引用的第一段中可以清楚地看出,如果

m
是固定大小的
Eigen::Matrix
专业化,那么它的数据将(因为它具有自动存储持续时间)存储在堆栈中。这是重要的保证,例如对于不允许动态内存分配的项目(例如嵌入式)。

事实上,Eigen 甚至提供了一个内部预处理器指令,

EIGEN_RUNTIME_NO_MALLOC
,可用于禁止 Eigen 模块内的任何动态内存分配。

这些宏主要供开发 Eigen 的人员使用 测试目的。尽管如此,它们可能对高级用户有用 以及出于调试和测试目的的好奇,他们 不应该 通过真实代码使用

EIGEN_RUNTIME_NO_MALLOC
- 如果定义,则会引入新的开关 可以通过调用来打开和关闭
set_is_malloc_allowed(bool)
。如果不允许
malloc
并且特征值 尝试动态分配内存,断言失败 结果。默认情况下未定义。

但是,强调不应该被实际代码使用,但 Eigen 用户可以将其用于测试目的。

固定大小的矩阵可能仍会出现在堆上!

正如@superjax 在评论中提到的:

我要补充的最后一件事是,超过 EIGEN_STACK_ALLOCATION_LIMIT 的固定大小矩阵也将在堆上分配。 (默认为128kb,但可以更改)


1
投票

m
与以这种方式声明的任何其他类型一样,具有 自动存储持续时间

当然,

Eigen::MatrixXd
将动态管理其大部分内部内存,但您不需要关心这一点。


0
投票

Eigen 库中的固定大小对象

所有固定尺寸的物体,例如Matrix2f、Vector3f 等使用声明到堆栈上的数组进行分配。如果您查看 Eigen/src/Core/DenseStorage.h

struct plain_array
{
  T array[Size];
  ...

Eigen 库中的动态大小对象

动态大小对象(以及运行时创建的中间对象)使用 malloc()/realloc() 获取内存。您可以在Eigen/src/Core/util/Memory.h

中查看它
© www.soinside.com 2019 - 2024. All rights reserved.