Why does this std::function and operator cause a segmentation fault?

Viewed 126

I don't see anything wrong with this code but it gives me a seg fault. Changing the std::function to a normal function solves the problem. Also removing the addition in the overloaded operator solves the problem. Also changing the Point constructor from const int& to int solves the problem. But I don't understand why. https://onlinegdb.com/Sy32UTllO

#include <iostream>
#include <functional>

struct Point
{
    int x, y;
    Point() {}
    Point(const int& x, const int& y) {}
};
Point operator+(const Point& p1, const Point& p2) { return {p1.x+p2.x, p1.y+p2.y}; }
Point p1, p2;
std::function<const Point&()> fn = []{ return p1; };

int main()
{
    Point p3 = fn() + p2;
    return 0;
}
2 Answers
std::function<const Point&()> fn = []{ return p1; };

Because you didn't specify the return value of the lambda, it defaults to returning it by value. So fn is trying to return a reference to a temporary, which is undefined behavior.

Do this instead:

std::function<const Point&()> fn = []() -> const Point& { return p1; };

[]{ return p1; } returns by value, so fn() returns a dangling reference.

Related