代码之家  ›  专栏  ›  技术社区  ›  Tommy Tsang

将lambda存储为std::函数时出现分段错误

  •  3
  • Tommy Tsang  · 技术社区  · 7 年前

    下面的代码给出了分段错误。调试后,我发现问题可以通过将lambda声明为auto而不是Function来解决。为什么会这样?

    #include <functional>
    #include <iostream>
    #include <vector>
    
    typedef std::vector<double> Vec;
    typedef std::function<const Vec&(Vec)> Function;
    
    
    int main()
    {
         //Function func = [](const Vec& a)->Vec /*this give me segfault*/
         auto func = [](const Vec& a)->Vec /*this work just fine??*/
             {
                  Vec b(2);
                  b[0] = a[0] + a[1];
                  b[1] = a[0] - a[0];
                  return b;
             };
         Vec b = func(Vec{1,2});
         std::cout << b[0] << " " << b[1] << "\n";
         return 0;
    }
    

    将此lambda表达式传递给其他一些类。

    std::vector>中的0x0000000000401896:在/usr/include/c++/5/bits/stl_向量处的大小(该值=0x0)。h: 655 655{return size\u type(this->\u M\u impl.\u M\u finish-this->\u M\u impl.\u M\u start); }

    #0 0x0000000000401896,标准::向量(>::在/usr/include/c++/5/bits/stl_向量处的大小(该值=0x0)。h:655
    #std::vector>中的1 0x00000000004015aa:向量(这=0x7FFFFFDC50,_ux=) at/usr/include/c++/5/bits/stl_矢量。h:320
    #2 0x0000000000400d12在主()中测试。cxx:18

    2 回复  |  直到 7 年前
        1
  •  6
  •   StoryTeller - Unslander Monica    7 年前

    const Vec&(Vec) 相当于一个看起来像这样的lambda (Vec) -> const Vec& .你通过一个 (const Vec&) -> Vec

    std::function

    分段错误很可能是由于lambda(临时)的返回值中固有的未定义行为被绑定到中的常量引用 std::函数 operator() ; 该引用将在 std::函数

        2
  •  1
  •   molbdnilo    7 年前

    你需要小心使用函数类型,如果使用正确的函数类型,它应该可以正常工作;

    typedef std::function<Vec(const Vec&)> Function; 
    

    随着对象包装器的减少和传统函数的增加,问题可能会变得更清楚。

    一旦你移除了通过对象的间接性,归结起来就是:

    // const Vec& -> Vec
    std::vector<double> the_lambda(const std::vector<double>& x)
    {
        return x;
    }
    
    // Vec -> const Vec&
    const std::vector<double>& the_function(std::vector<double> x)
    {
        return the_lambda(x);
    }
    
    
    int main()
    {
        std::vector<double> v = {1, 2};
        std::vector<double> lv = the_lambda(v);    // OK.
        std::vector<double> fv = the_function(v);  // Undefined.
    }
    

    这可以编译,但g++警告说 the_function std::function (但没有编译器的提示)。

    std::函数 是一个错误。如果你使用函数指针,你是不会逃脱惩罚的,而C++应该是这样的