the begin()
and end()
pointers/iterators used to determine what is to be copied are evaluated once when the function is called. So essentially std::copy()
will increment it's cursor iterator which will eventually reach end()
, because vector<T>::const_iterator
is just a fancy T*
pointer on an old school array.
As you correctly mentionned, if a push_back
makes the vector
reallocate and move the data somewhere else in memory, then the next element copied will have a wrong address for source, which is likely to end up with a segmentaion fault.
For a list, it can never terminate because end()
is a sentinel/guard pointer, and you can only reach end()
by incrementing the iterator on the last element of the list. So the address of end()
itself never changes, but because you are constantly adding an element at the end of the list, you will never reach the last element, so std::copy()
can never obtain a pointer to end()
. Kind of like a dog chasing it's tail.
It's easier to understand with illustrations and diagrams, read-up on doubly linked list and sentinel nodes, it will all make sense.