C ++ лямбда захватывает указатель с другим значением - PullRequest
0 голосов
/ 29 марта 2020

У меня есть этот фрагмент кода, который регистрирует обратный вызов обработчика событий Boost asio. Ключевой точкой является значение pliny_store_ptr в трех лог-точках psp. Каким-то образом захват работает не так, как я ожидаю.

// This gives me a db pointer that works.
sqlite3* pliny_store_ptr = sqlite_open_v2(...);
LOG_INFO << "psp[1]: " << pliny_store_ptr;
UdpServer udp_server(
    io_service_main, udp_port,
    [&pliny_store_ptr, &callback, &io_service_worker,
     &work_thread_idle](const string& epistula_stream) -> string {
        LOG_INFO << "psp[2]: " << pliny_store_ptr;
        return "IRL a function returning a string";
    });
io_service_main.run();
LOG_INFO << "psp[3]: " << pliny_store_ptr;

Известно, что класс UdpServer работает в других контекстах, включая собственные модульные тесты. Это просто оболочка для некоторых обработчиков чтения asio asyn c: она прослушивает udp_port сообщения. Третий аргумент, лямбда, является обратным вызовом, который UdpServer будет вызывать в процедуре завершения обработчика чтения asio asyn c. Все довольно обычные вещи.

(Все это выполняется в одном потоке. И, очевидно, постоянное возвращаемое значение действительно является функцией обратного вызова, которая использует те переменные, которые захватывает лямбда-выражение.)

Вывод работает это ниже. Обратите внимание на три точки журнала psp: в 1 и 3 значение равно 0x24632b8, но в 2 (зафиксированное значение) оно равно 0x293b570. Поэтому неудивительно, что вызов sqlite3 выдает ошибку 21: дескриптор передаваемой базы данных недопустим.

Вопрос в том, почему я не фиксирую правильное значение для pliny_store_ptr в лямбде. Я попытался сделать лямбду непостоянной, думая, что sqlite3 захочет изменить то, на что указывает, и, возможно, я бы неправильно понял кое-что о константности указателей в лямбдах. Кажется, не имеет значения. Первоначально я передал pliny_store_ptr по значению, которое, как я думал, будет работать (это указатель, а не содержимое), но также не сработало примерно так же.

Кто-нибудь видит, что я неправильно понимаю?

2020-Mar-29 16:55:58.373760: psp[1]: 0x24632b8
2020-Mar-29 16:55:59.378286: psp[2]: 0x293b570
2020-Mar-29 16:56:00.377609: psp[2]: 0x293b570
2020-Mar-29 16:56:01.376113: psp[2]: 0x293b570
2020-Mar-29 16:56:02.376682: psp[2]: 0x293b570
2020-Mar-29 16:56:03.375930: psp[2]: 0x293b570
2020-Mar-29 16:56:04.376944: psp[2]: 0x293b570
2020-Mar-29 16:56:05.375787: psp[2]: 0x293b570
2020-Mar-29 16:56:05.831849: psp[2]: 0x293b570
2020-Mar-29 16:56:05.832640: INSERT INTO pliny_tasks (client_id, initiator_timestamp, registered_timestamp, campaign_id, reading_group_id, reading_group_type, user_id, device_id)  VALUES (8864268719399569257, 1585500965829, 1585500965832, 0, 5, 'galley', 0, '');
2020-Mar-29 16:56:05.832789: Failed to insert task: err=21) - library routine called out of sequence
2020-Mar-29 16:56:06.376993: Quit requested, preparing to terminate pliny services.
2020-Mar-29 16:56:06.377428: Pliny services ready for termination.
2020-Mar-29 16:56:06.377676: psp[3]: 0x24632b8

...