下面这段代码运行会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呢
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.
大家讲道理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
)