不明原因使用犰狳种类
编辑:更新的代码,以使两个功能更类似于不明原因使用犰狳种类
我有一个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;
}
这个例子崩溃,其中值得注意的是,有和没有“使用命名空间ARMA;”包括带有和不带#define ARMA_USE_CXX11,并使用32位和64位存储器地址。
我不知道我在lambda函数中做了什么错误,或者如果它是犰狳引起的问题。如果我删除等式的一部分(例如标量的乘法),它将正常工作。
任何帮助表示赞赏。
由于
的Henrik
犰狳大量使用惰性计算的,并具有大量的由参考保持其它中间体具有有限寿命的中间结果。在这里来咬你的那个人是min
的返回值,并且你尝试返回它。
如果您改变拉姆达这样的:
auto fLambda = [&](double value) -> rowvec2 { return min(vA * const1, vB * const2); };
也就是说,如果你明确指定,它返回一个rowvec2
,而不是你从min
得到Glue<eOp<rowvector2, eop_scalar_times>, eOp<rowvector2, eop_scalar_times>, glue_min>
,问题应该消失,因为中间结果是在函数返回之前转换为有形的东西。
是的,真的。你可以在/usr/include/armadillo_bits/Glue_bones.hpp
看到这个。它们根本不是要存储的。
加1:啊,“'操作符自动'”/依赖引用生存期延长问题。 (已经有一些建议来调整rype更改从中推导出什么样的值类型 - 因为这个原因 - 我将其称为'operator auto') – Yakk 2015-02-10 16:32:11
我们可以使用一个'store'函数来实现这个目的吗?或者是从表达式模板中推导出的预期存储类型(所以我们可以写一个)? – Yakk 2015-02-10 16:34:23
@Yakk嗯......应该有可能(并且非常困难)推断出存储类型,但我认为目前这些设施并不在Armadillo中。我的意思是,'eOp'的存储类型是它的参数的存储类型,矩阵向量乘法的存储类型是一个向量 - 实现它会是一些工作,因为它会触及每一个操作,但它不会'不是火箭科学。 – Wintermute 2015-02-10 16:45:56
我看到两个区别。首先,lambda中的引用是'const&',而在函数中它们是'&'。其次,'funcLambda'构建,而'fLambda'确实分配。如果消除这些差异,行为是否会改变? – Yakk 2015-02-10 15:57:02
@Yakk:我改变了对函数中const&的引用,并使得两个函数调用都做了赋值。尽管如此。代码在原始问题中更新。 – Henrik 2015-02-10 16:06:40