Область действия локальных переменных, захваченных лямбда-функцией (C ++) - PullRequest
0 голосов
/ 16 октября 2019

Я искал везде, но не смог найти ответ на свой вопрос. Я пытаюсь написать пример, который показывает, что захват локальной переменной включающей функции по ссылке опасен, потому что она может больше не существовать, когда на нее действительно ссылаются. Вот мой пример:

#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 и модифицирует ее.

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

выводит значение мусора, которое указывает, что что-то пошло не так, как ожидалось. Однако

test(test2(100));

выводит «111». Это сбивает с толку меня, так как я думал, что когда test2 (100) возвращает лямбда-функцию типа std :: function, стековый фрейм для test2 исчезнет, ​​и при вызове test он не сможет получить доступ к значению k,Буду признателен за любые идеи или ключевые слова, которые я могу использовать для поиска ответов.

1 Ответ

0 голосов
/ 16 октября 2019

Я провел ваш тест на моей машине, и результаты в обоих случаях соответствуют ожидаемому общему количеству мусора. Наличие правильного ответа время от времени в этом качестве очень вводит в заблуждение. Повисшая ссылка или указатель могут иногда указывать на одно и то же значение, если указанная память еще не занята другим значением.

В двух словах, лямбды C ++ не увеличивают время жизни захваченногоссылки / указатели должны развернуть их стек ссылок. То же самое относится и к захвату указателя «this» класса. Если класс выходит из области видимости, 'this->' приведет к совершенно неопределенному поведению.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...