Why are std::begin and std::end "not memory safe"?
The get_data
function returns an object. When used the way shown, that object will be a temporary object, which will be destructed once the full expression ends. The iterator now references a vector object which no longer exists, and can't be dereferenced or used in any useful way.
I think Eric's point about std::begin
is that it silently accepts an rvalue container as an argument to begin with. On the face of it, the problem with the code is also exemplified in
auto it = get_data().begin();
But std::begin
is a free function template, it can be made to reject rvalues without needing to add the proper reference qualifiers to each container's begin
members. By "just" forwarding it misses an opportunity to add a layer of memory safety to code.
Ideally, the overload set could have benefited from the addition of
template< class C >
void begin( C&& ) = delete;
That one would have caused the code in the blog post to be flat out rejected on the spot.
The temporary vector returned by get_data
goes out of scope after std::begin
is done. It is not kept alive, so it
is an iterator into a destroyed object.