Home  >  Q&A  >  body text

c++ - lambda 递归为何会crash

下面这段代码运行会crash

#include <iostream>
#include <windows.h>
int main() {
        std::function<void()> fun = [=]{
                std::cout << "AAA" << std::endl;
                Sleep(1000);
                fun();
        };
        fun();
        return 0;
}

复制代码
把[=]改成[&] 就能通过了

#include <iostream>
#include <windows.h>
int main() {
        std::function<void()> fun = [&]{
                std::cout << "AAA" << std::endl;
                Sleep(1000);
                fun();
        };
        fun();
        return 0;
}

复制代码
而我的函数需要用[=]方式,为啥会crash呢

巴扎黑巴扎黑2715 days ago683

reply all(2)I'll reply

  • ringa_lee

    ringa_lee2017-04-17 12:59:58

    fun must be constructed first and then called, but since it is a value copy, the fun copied when fun is constructed may be incomplete.

    warning: variable 'fun' is uninitialized when used within its own initialization [-Wuninitialized]
                    fun();
                    ^~~

    If you must also copy fun (capture by value), you can use the delay method:

    #include <iostream>
    #include <windows.h>
    int main() {
            std::function<void()> fun = [=, &fun]{
                    std::function<void()> delayFun = [&]{
                            std::function<void()> funCopy = fun;
                            funCopy();
                    };
                    std::cout << "AAA" << std::endl;
                    Sleep(1000);
                    delayFun();
            };
            fun();
            return 0;
    }

    There is no warning, and the program behaves as expected.

    reply
    0
  • 大家讲道理

    大家讲道理2017-04-17 12:59:58

    In the first piece of code, you implement the fun() function by copying, that is, every time fun() is called, a copy will be made at the same time, and then another copy will be made inside the copy, and this will be repeated several times. In the future, there will be many fun() recursing at the same time. This is a process of geometric growth. This is a bit like the linux function in fork. If fork is written in a loop, the process coming out of fork will also be a geometric growth process. However, this copy + recursion process is still relatively complicated and difficult to explain clearly in one sentence. If you are interested, you can search for fork related articles, which will be helpful for you to understand this issue

    The second piece of code will not copy a new function, so there is only one fun() recursing. This is a linear growth process (but when the recursion reaches the limit, there will still be crash, but it takes a long time. Long, because there will be 1 second between the two recursions. If you remove the Sleep(), you should see it crash)

    .

    reply
    0
  • Cancelreply