使用Armadillo类型的lambda函数崩溃的未知原因

时间:2015-02-10 15:47:06

标签: c++ lambda crash armadillo

编辑:更新了代码以使两个函数更相似

我在lambda函数中使用armadillo类型时遇到问题,当某些东西试图读取无效的内存位置时会导致崩溃。如果我将相同的表达式移动到正常函数中,一切都会顺利进行。

所以,简单的工作示例:

#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;
}

此示例在使用命名空间arma时使用和不使用&#34;使用和不使用命名空间arma崩溃;&#34;包含,包含和不包含#define ARMA_USE_CXX11,并使用32位和64位内存地址。

我不知道我是否在lambda函数中做错了什么,或者是否是导致问题的犰狳。如果我删除等式的部分(例如标量的乘法),它将正常工作。

感谢任何帮助。

由于

的Henrik

1 个答案:

答案 0 :(得分:3)

Armadillo大量使用惰性评估,并且具有大量中间结果,通过引用 1 来保留其他具有有限寿命的中间体。在这里咬你的是min的返回值,并且你试图在你得到它时返回它。

如果你改变你的lambda:

auto fLambda = [&]( double value ) -> rowvec2 { return min( vA * const1, vB * const2 ); };

也就是说,如果您明确指定它返回rowvec2而不是Glue<eOp<rowvector2, eop_scalar_times>, eOp<rowvector2, eop_scalar_times>, glue_min>来自min,则问题应该消失,因为中间结果转换为有形的东西在函数返回之前。

1 是的,真的。您可以在/usr/include/armadillo_bits/Glue_bones.hpp中看到此信息。它们根本不存储。