1

c++ newbie here. I'm having trouble understanding the difference between these two methods. What does 'in-place' means in this context. Docs http://www.cplusplus.com/reference/memory/uninitialized_copy/

Unlike algorithm copy, uninitialized_copy constructs the objects in-place, instead of just copying them.

I'm reading the book Accelerated C++ by Andrew Koenig and Barbara E. Moo, and it also seems a bit vague when explaining the differences

The uninitialized_copy function operates like the library copy function [...] It assumes that the target range contains raw storage, rather than elements that already hold values.

But then what happens if you call unitialized_copy on a piece of memory that already contains elements? I've tried it out and it seems to work just fine but I'm sure there's a good reason for having two different functions, I'd like to know what that reason is.

frankelot
  • 13,666
  • 16
  • 54
  • 89
  • From [the Possible Implementation given here](https://en.cppreference.com/w/cpp/memory/uninitialized_copy) it looks like it uses [placement new](https://en.cppreference.com/w/cpp/language/new#Placement_new) on the given storage without cleaning up anything that's already there. If there were any valid objects in that storage, they get written over without being destroyed. No destructor, no RAII, no clean-up. Quite likely leak -city. – user4581301 Mar 29 '20 at 04:45
  • For what it's worth, cplusplus.com has a reputation around here for not being a good source. cppreference.com is usually considered to be better. –  Mar 29 '20 at 04:50
  • 4
    Does this answer your question? [Difference between std::uninitialized\_copy & std::copy?](https://stackoverflow.com/questions/30158192/difference-between-stduninitialized-copy-stdcopy) – Boris Lipschitz Mar 29 '20 at 04:55
  • @user4581301 I think this must be true, but I find it weird that this being the key difference is not mentioned explicitly in the docs. – frankelot Mar 29 '20 at 15:50
  • @BorisLipschitz kindof, is that answer implying that `copy` will call the assignment constructor on the existing memory object... and uninitialized_copy will call the copy constructor instead? – frankelot Mar 29 '20 at 15:53

2 Answers2

3

What does 'in-place' means in this context.

To construct an object "in-place", using placement-new expression, means that there is an existing span of storage into which the object is constructed. This is in contrast with allocating-new, which allocates a new piece of dynamic storage into which the object is created.

But then what happens if you call unitialized_copy on a piece of memory that already contains elements?

Depends on the type of existing objects. If the type is trivially destructible, then the lifetimes of the overwritten objects are ended.

If the type is not trivially destructible, then constructing objects into their place using std::unitialized_copy results in undefined behaviour.


Note that in contrast, std::copy does not create any objects. It calls the assignment operator on existing objects whose lifetime is not affected by the operation. (Although, an overloaded assignment operator may indirectly result in creation of objects).

A case where std::uninitialized_copy is useful is reusal of raw memory, such as in the implementation of std::vector.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • So, is it correct to say `copy` will call the assignment constructor/operator on the existing memory object... and `uninitialized_copy` will call the `copy constructor` of the object you are inserting and place the result on the memory (overwriting whatever was there) – frankelot Mar 29 '20 at 16:01
  • 1
    @FRR There is no such thing as an assignment constructor. But otherwise, yes. – eerorika Mar 29 '20 at 17:34
1

The std::uninitialized_copy is there for very special cases where you have to pass objects to a memory that's under your explicit control, for example using a special memory allocator, reserved memory areas and so on.

So if you don't have very good reason to use std::uninitialized_copy, don't use it.

dlask
  • 8,776
  • 1
  • 26
  • 30