std::unitialized_copy
is used when arr2
only points to an uninitialized memory region. For example, if you used malloc
. In this way std::uninitialized_copy
is responsible, first, to initialize the container that will host the elements and then make the copy.
On the other hand, std::copy
is limited to copying the elements.
And what is an uninitialized memory region?
Uninitialized memory means that which has been reserved with, for example, malloc
. A function inherited from C that only reserves memory, that is, does not invoke any constructor implicitly.
If we talk about native types (pointer to int
, for example), there is no difference. But if we talk about objects then the thing changes since an uninitialized object is not safe to use since it does not have a valid state.
An example:
void* memoria = malloc(1000);
std::string * str = reinterpret_cast<std::string*>(memoria);
*str = "abcdef"; // Más que probable error en ejecución.
So, when can not can std::copy
be used?
Basically when we have a memory region not initialized .
A silly example taken from the documentation . when replacing std::uninitialized_copy
with std::copy
we get a nice segmentation error:
int main()
{
const char *v[] = {"This", "is", "an", "example"};
auto sz = std::size(v);
if(void *pbuf = std::aligned_alloc(alignof(std::string), sizeof(std::string) * sz))
{
try
{
auto first = static_cast<std::string*>(pbuf);
auto last = std::copy(std::begin(v), std::end(v), first);
for (auto it = first; it != last; ++it)
std::cout << *it << '_';
std::destroy(first, last);
}
catch(...) {}
std::free(pbuf);
}
}
On the other hand, using std::uninitialized_copy
when we already have the initialized memory could create memory leaks, since we will not try to destroy what already exists in the memory. When the memory is initialized, the corresponding constructor will be invoked and that could cause pointers to be lost to regions of memory reserved by the object that existed in that region of memory.