A question about the using of std::uninitialized_copy

The following codes can be executed correctly,and print 1 2 3

std::allocator<int> alloc;
auto begin = alloc.allocate(3);
std::vector<int> ivec = { 1,2,3 };
std::uninitialized_copy(ivec.begin(), ivec.end(), begin);
for (auto q = begin; q != begin + 3; ++q)
cout << *q << " ";
alloc.deallocate(begin, 3);

But,the following codes can not be executed, when the program is running,there is an error : cannot seek vector iterator after end

std::vector<int> ivec_1 = { 1,2,3 };
std::vector<int> ivec_2;
ivec_2.reserve(3);
std::uninitialized_copy(ivec_1.begin(), ivec_1.end(), ivec_2.begin());

My question is: First of all,I know the error is because the iterator exceeds after-end iterator. Generics algorithms which require three iterators always assume that destination sequences at least have the same length as source sequences.In other word,destination sequences must be able to contain all elements from source sequences.But, "The same length" here refer to what ?

1. The quantity of actual elements between source sequences and destination sequences is the same ?
2. The quantity of memories(not actual element is required) that source sequences and destination sequences have is the same ?

If it requires the same quantity of actual elements. Why doesn't the first code report errors ? I use std::allocator to allocate 3 memories. And these memories are uninitialized, there are no elements constructed in these memories. But std::uninitialized succeed in copying the elements from source sequences to destination sequences.

If it requires the same quantity of memories(not actual element is required). Then why the second code report an error ? At first, ivec_2 is empty. And I call reserve(3) to allocate 3 memories previously for it. I even call capacity() to make sure that it actually allocates 3 memories.And there are no actual elements in ivec_2.But this time std::uninitialized_copy doesn't work and report an error.
First of all,I know the error is because the iterator exceeds after-end iterator.

Doesn't this answer your question?

You're not supposed to do anything with memory that has been reserved but is currently not used to store any elements in the vector. This has nothing to do with std::uninitialized_copy.
ivec_2.reserve(3);
This doesn't change the size of the vector or the end-iterator position. It simply means that any future reallocation won't occur until (at least) this limit is breached.

Perhaps you meant
ivec_2.resize(3);
Thank you.But
You're not supposed to do anything with memory that has been reserved but is currently not used to store any elements
, when I use std::allocator to allocate memories,these memories are currently not used to store any elements either and they are uninitialized , but I can use std::uninitialized_copy to copy elements to these memories. I just feel strange.
Debug versions of the library may be (typically would be) using checked / safe iterators. So there would be a check to verify that we are not going out of bounds (beyond the logical end) of the vector.

Microsoft: https://docs.microsoft.com/en-us/cpp/standard-library/checked-iterators?view=msvc-170
GNU: https://gcc.gnu.org/onlinedocs/libstdc++/manual/debug_mode_design.html#debug_mode.design.methods.safe_iter

There is no such check when we use a raw pointer (as in the case of memory allocated by std::allocator)

Yes ! I tried to disable the check of iterators and the second code can be executed correctly now.Thank you JLBorges !
Topic archived. No new replies allowed.