I found this piece of code at https://alexgaynor.net/2019/apr/21/modern-c++-wont-save-us/. The author says that
in main x goes out of scope, destroying the last reference to the data, and causing it to be freed. At this point y contains a dangling pointer.
But, actually, y() is already dangling inside that scope. With a gcc implementation I tried, it outputs
2
1
3
in line with that.
What is going on here and how would you summarize the reason for the undefined behaviour that is occurring?
My understanding is that the object corresponding to the labda holds a ref to the shared_ptr x that is captured, but the shared_ptr object itself is passed in by value, so thats gonna be a dangling reference to that because of the automatic lifetime of x (as an argument in f). So, when y() is invoked, the () operator is going to do some .operator*() on that x reference, is that correct? So, the dangling pointer has nothing to do with the refcount of that x shared_ptr inside main at the end of the day in that case and the author is simply wrong?
#include <memory>
#include <iostream>
#include <functional>
std::function<int(void)> f(std::shared_ptr<int> x) {
return [&]() { return *x; };
}
int main() {
std::function<int(void)> y(nullptr);
{
std::shared_ptr<int> x(std::make_shared<int>(1));
y = f(x);
std::shared_ptr<int> u(std::make_shared<int>(2));
std::cout << y() << std::endl;
std::cout << *x << std::endl;
}
std::shared_ptr<int> v(std::make_shared<int>(3));
std::cout << y() << std::endl;
}