Lambda函数(C ++)捕获的局部变量的范围

时间:2019-10-16 10:16:19

标签: c++ function lambda stack call

我到处搜索,但找不到我的问题的答案。我正在尝试编写一个示例,该示例表明通过引用捕获封闭函数的局部变量是危险的,因为在实际引用它时可能不再存在该变量。这是我的示例:

#include <iostream>


std::function<int (int)> test2(int l) {
       int k = 10;
       return [&] (int y) { return ++k + 100; };
}


void test(std::function<int (int)> k) {
        std::cout << k(100);
}

int main() {
        test(test2(100));

        std::function<int (int)> func = test2(100);
        test(func);

        return 0;
}

我试图通过尝试从 test2 返回一个捕获了局部变量 k的lambda函数,来尝试访问和修改堆栈框架上不存在的局部变量,从而重现堆栈损坏并对其进行修改。

std::function<int (int)> func = test2(100);
test(func);

打印出一个垃圾值,该值指示出了预期的问题。但是,

test(test2(100));

打印出“ 111”。这让我感到困惑,因为我认为当test2(100)返回类型为std :: function的lambda函数时,test2的堆栈框架将消失,并且在调用test时,它应该无法访问k的值。我会感谢任何可用于搜索答案的想法或关键字。

1 个答案:

答案 0 :(得分:0)

我已经在计算机上运行了您的测试,两种情况下的结果均与预期的总垃圾相同。偶尔以这种身份获得正确答案会产生误导。只要指向的内存尚未被其他值占用,悬挂的引用或指针有时可能会指向相同的值。

简而言之,如果C ++ lambda不能扩展捕获的引用/指针的生存期,则它们的引用堆栈将消失。同样的事情也适用于捕获类的“ this”指针。如果该类超出范围,则“ this->”将导致完全未定义的行为。