[踩坑] Eigen 惰性求值与生命周期
引入
做作业时遇到个诡异的问题:
1 |
|
按照上面的写法,是正常运行的,而按照注释的写法,得到的就是非常大的数字,明显是不正确的。这两种方法看上去区别不是很大,那么问题出在哪里呢?
分析
看一下相关的定义:
1 |
|
似乎是没什么问题,flatten(grad_g)
的值被 const MatrixBase<Rhs>&
常值引用,在 solve
函数内是不会失效的。于是继续深入。
1 |
|
到这里,flatten(grad_g)
的值还是没有失效的,但我们可以看到,solve
函数实际上并没有进行求解,只是构造了一个 Solve
对象。这是 Eigen 的懒惰求值特性,由于用了 auto
变量接受返回值,所以得到的还是 Solve
对象,这点在 IDE 的提示中也可以看到。
当后面使用 delta_X_flatten
的时候,由于它是一个引用了 flatten(grad_g)
临时对象的 Solve
对象,而 flatten(grad_g)
已经被析构了,便会造成悬垂引用,产生错误。
解决
解决方法有两个,一个是像上面一样,先把 flatten(grad_g)
赋值给 grad_g_flatten
,grad_g_flatten
的生命周期足够长,就不会悬垂引用了;另一个是指明 delta_X_flatten
的类型为 MatrixXd
,这样在赋值的时候,就会触发求值,后面不再依赖这个临时变量,也就不会悬垂引用了。
[踩坑] Eigen 惰性求值与生命周期
http://xiao-h.com/2025/02/19/踩坑-Eigen惰性求值与生命周期/