我正在学习 C++ lambda 函数。为什么它有这个输出?
I'm learning C++ lambda function. Why does it have this output?
这是我的代码
#include<iostream>
int* p = nullptr;
auto fun()
{
int a = 1;
p = &a;
std::cout << &a << std::endl;
auto z = [&a]() {std::cout << &a << " "; a++; std::cout << "lambda call " << a << std::endl; };
return z;
}
int main()
{
auto z = fun();
std::cout << *p << "\n";
z();
z();
fun()();
}
输出为
0x7fffd10af15c
1
0x7fffd10af15c lambda call 21880
0x7fffd10af15c lambda call 21880
0x7fffd10af15c
0x7fffd10af15c lambda call 21880
我的编译器版本是gcc 9.4.0版(Ubuntu9.4.0-1ubuntu1~20.04.1)
为什么我有这个输出?这是未定义的行为吗?
是的,问题是 a
是 fun
函数中的局部变量,在 fun
完成时被销毁。这意味着,返回的 lambda z
引用了堆栈上的一个区域,其中 a
曾经是,但现在当 z
被调用时,这个区域被用于其他用途(这就是为什么你参见 21880)。
为了避免这个问题,你需要防止 a
在离开 fun
的范围时被销毁。一种方法是将 a
声明为全局变量,就像 p
一样。另一种是让它成为静态变量。
Why do i have this output?
给定的程序有未定义的行为,因为a
是一个局部变量,一旦函数returns就会被销毁,所以它(a
) 不应再次引用。
Undefined behavior means anything1 can happen including but not limited to the program giving your expected output. But never rely(or make conclusions based) on the output of a program that has undefined behavior. The program may just crash.
所以您看到(也许看到)的输出是未定义行为的结果。正如我所说,不要依赖具有 UB 的程序的输出。程序可能会崩溃。
因此,使程序正确的第一步是删除 UB。 然后并且只有那时你可以开始对程序的输出进行推理。
要解决此问题,请确保您不会通过将局部变量(a
)设为 static
或 global
.[=18 来引用超出其范围的局部变量=]
1有关未定义行为的更技术准确的定义,请参阅 this 其中提到:没有对程序行为的限制.
这是我的代码
#include<iostream>
int* p = nullptr;
auto fun()
{
int a = 1;
p = &a;
std::cout << &a << std::endl;
auto z = [&a]() {std::cout << &a << " "; a++; std::cout << "lambda call " << a << std::endl; };
return z;
}
int main()
{
auto z = fun();
std::cout << *p << "\n";
z();
z();
fun()();
}
输出为
0x7fffd10af15c
1
0x7fffd10af15c lambda call 21880
0x7fffd10af15c lambda call 21880
0x7fffd10af15c
0x7fffd10af15c lambda call 21880
我的编译器版本是gcc 9.4.0版(Ubuntu9.4.0-1ubuntu1~20.04.1) 为什么我有这个输出?这是未定义的行为吗?
是的,问题是 a
是 fun
函数中的局部变量,在 fun
完成时被销毁。这意味着,返回的 lambda z
引用了堆栈上的一个区域,其中 a
曾经是,但现在当 z
被调用时,这个区域被用于其他用途(这就是为什么你参见 21880)。
为了避免这个问题,你需要防止 a
在离开 fun
的范围时被销毁。一种方法是将 a
声明为全局变量,就像 p
一样。另一种是让它成为静态变量。
Why do i have this output?
给定的程序有未定义的行为,因为a
是一个局部变量,一旦函数returns就会被销毁,所以它(a
) 不应再次引用。
Undefined behavior means anything1 can happen including but not limited to the program giving your expected output. But never rely(or make conclusions based) on the output of a program that has undefined behavior. The program may just crash.
所以您看到(也许看到)的输出是未定义行为的结果。正如我所说,不要依赖具有 UB 的程序的输出。程序可能会崩溃。
因此,使程序正确的第一步是删除 UB。 然后并且只有那时你可以开始对程序的输出进行推理。
要解决此问题,请确保您不会通过将局部变量(a
)设为 static
或 global
.[=18 来引用超出其范围的局部变量=]
1有关未定义行为的更技术准确的定义,请参阅 this 其中提到:没有对程序行为的限制.