这个问题可能很愚蠢,但我是初学者。 当我在本地范围内创建 Eigen::MatrixXd 时,如下所示:
void foo(){
Eigen::MatrixXd m(rows,cols);
// do stuff
}
对象会在堆上还是在栈上? 我希望它在堆栈上,因为我不使用“new”关键字。
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,但可以更改)
m
与以这种方式声明的任何其他类型一样,具有 自动存储持续时间。
当然,
Eigen::MatrixXd
将动态管理其大部分内部内存,但您不需要关心这一点。
Eigen 库中的固定大小对象
所有固定尺寸的物体,例如Matrix2f、Vector3f 等使用声明到堆栈上的数组进行分配。如果您查看 Eigen/src/Core/DenseStorage.h,
struct plain_array
{
T array[Size];
...
Eigen 库中的动态大小对象
动态大小对象(以及运行时创建的中间对象)使用 malloc()/realloc() 获取内存。您可以在Eigen/src/Core/util/Memory.h
中查看它