使用 Armadillo 类型的 lambda 函数崩溃的未知原因
Unknown cause of crash in lambda function using Armadillo types
编辑:更新代码使两个函数更加相似
我在 lambda 函数中使用犰狳类型时遇到问题,当某些东西试图读取无效的内存位置时会导致崩溃。如果我将相同的表达式移动到普通函数中,一切都会顺利进行。
所以,简单的工作示例:
#define ARMA_USE_CXX11
#include <armadillo>
using namespace arma;
rowvec2 funcLambda( double value, const rowvec2 &vA, const rowvec2 &vB, const double &const1, const double &const2 ){
return min( vA * const1, vB * const2 );
}
int main( void ){
rowvec2 vA = {.12, .44};
rowvec2 vB = {2, 2};
auto const1 = double( 1.2 );
auto const2 = 3.1;
auto fLambda = [&]( double value ){ return min( vA * const1, vB * const2 );};
rowvec2 z = rowvec2({0.0, 0.0});
// This works fine
z = funcLambda( 100, vA, vB, const1, const2 );
// This crashes
z = fLambda( 100 );
return 1;
}
这个例子在注释所在的地方崩溃,包含和不包含 "using namespace arma;" 行,包含和不包含 #define ARMA_USE_CXX11,以及使用 32 位和 64 位内存寻址。
我不知道是我在 lambda 函数中做错了什么,还是犰狳引起了问题。如果我删除等式的一部分(例如标量的乘法),它将正常工作。
感谢任何帮助。
谢谢
亨里克
犰狳大量使用惰性求值,并有大量的中间结果,这些中间结果通过引用1 持有其他生命周期有限的中间结果。在这里咬你一口的是 min
的 return 值,你在得到它时试图 return 它。
如果您像这样更改 lambda:
auto fLambda = [&]( double value ) -> rowvec2 { return min( vA * const1, vB * const2 ); };
也就是说,如果你明确指定它 return 是 rowvec2
而不是你从 min
得到的 Glue<eOp<rowvector2, eop_scalar_times>, eOp<rowvector2, eop_scalar_times>, glue_min>
,问题应该消失,因为中间结果在函数 returns.
之前转换为有形的东西
1 是的,真的。您可以在 /usr/include/armadillo_bits/Glue_bones.hpp
中看到这一点。它们根本不应该存储。
编辑:更新代码使两个函数更加相似
我在 lambda 函数中使用犰狳类型时遇到问题,当某些东西试图读取无效的内存位置时会导致崩溃。如果我将相同的表达式移动到普通函数中,一切都会顺利进行。
所以,简单的工作示例:
#define ARMA_USE_CXX11
#include <armadillo>
using namespace arma;
rowvec2 funcLambda( double value, const rowvec2 &vA, const rowvec2 &vB, const double &const1, const double &const2 ){
return min( vA * const1, vB * const2 );
}
int main( void ){
rowvec2 vA = {.12, .44};
rowvec2 vB = {2, 2};
auto const1 = double( 1.2 );
auto const2 = 3.1;
auto fLambda = [&]( double value ){ return min( vA * const1, vB * const2 );};
rowvec2 z = rowvec2({0.0, 0.0});
// This works fine
z = funcLambda( 100, vA, vB, const1, const2 );
// This crashes
z = fLambda( 100 );
return 1;
}
这个例子在注释所在的地方崩溃,包含和不包含 "using namespace arma;" 行,包含和不包含 #define ARMA_USE_CXX11,以及使用 32 位和 64 位内存寻址。
我不知道是我在 lambda 函数中做错了什么,还是犰狳引起了问题。如果我删除等式的一部分(例如标量的乘法),它将正常工作。
感谢任何帮助。
谢谢
亨里克
犰狳大量使用惰性求值,并有大量的中间结果,这些中间结果通过引用1 持有其他生命周期有限的中间结果。在这里咬你一口的是 min
的 return 值,你在得到它时试图 return 它。
如果您像这样更改 lambda:
auto fLambda = [&]( double value ) -> rowvec2 { return min( vA * const1, vB * const2 ); };
也就是说,如果你明确指定它 return 是 rowvec2
而不是你从 min
得到的 Glue<eOp<rowvector2, eop_scalar_times>, eOp<rowvector2, eop_scalar_times>, glue_min>
,问题应该消失,因为中间结果在函数 returns.
1 是的,真的。您可以在 /usr/include/armadillo_bits/Glue_bones.hpp
中看到这一点。它们根本不应该存储。