c++ - lambda 递归为何会crash
巴扎黑
巴扎黑 2017-04-17 12:57:58
0
2
701

下面这段代码运行会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呢

巴扎黑
巴扎黑

reply all(2)
左手右手慢动作

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.

大家讲道理

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)

.
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!