1

In the code below, line with pm, will that line move entire memory and assign it to pm or it will only move the memory p is pointing to but not the whole array?

   int main()
    {
        int* p{ new int[10]{0} };
        int* pm{ move(p) };//WILL THIS LINE MOVE THE ENTIRE MEMORY ALLOCATED FOR p THAT IS ENTIRE ARRAY or only the memory p is pointing to?
        return 0;
    }
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
There is nothing we can do
  • 23,727
  • 30
  • 106
  • 194
  • 2
    The question doesn't even make sense. The array **is** the memory `p` is pointing to, so it makes no sense to say "does it move the array or the memory `p` points to?" They're the same thing. Anyway, it doesn't move any memory at all. It makes the pointer `pm` point to the same memory as `p`. You can't move memory. – Jonathan Wakely Oct 17 '15 at 16:48
  • 1
    You are confusing move semantics with something like `memmove`. – el.pescado - нет войне Oct 17 '15 at 17:48

2 Answers2

4

It'll copy the pointer p into the pointer pm.

"Moving" pointers makes no sense because:

  • they have no move constructor
  • they have no move assignment operator
  • they are trivially simple and there is nothing to gain from moving them

Your expectation that the entire array will be somehow "moved" also makes no sense because:

  • you are already only obtaining handles to the same data, so there's nowhere for it to move to
  • the type int* has no knowledge about the data its instances may point to

Remember that the terribly-named std::move doesn't actually move anything. It just gives you an rvalue out of a name that might otherwise be treated as an lvalue.

In this case, the distinction is irrelevant, so it's as if you didn't write move at all.

Move semantics are useful for larger, more complex objects that indirectly manage memory, for example using pointers. You would expect the move constructor or move assignment operator for such a type to swap pointers. That's as far as the abstraction goes; that's the extent of its usefulness.

Trying to apply the same logic to pointers themselves just doesn't have any meaning, except in the case of a unique_ptr where this abstraction is found in its very purest form, because such an object is an extremely thin wrapper over a naked pointer. It's still only the wrapper that gets moved.

The best you could do would be to copy p into pm, then arbitrarily make p "invalid" by setting it to some unusable value. Again, pretty useless.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
3

Check out What are move semantics? for more details.

Pointers are "like" integers, they contain "addresses". The following code

int* pm{ move(p) };

Is semantically equivalent to

int* pm = p;

Which effect is simply to copy the "address" held by p into pm (think of it as an integer assignment).

Therefore the memory pointed to by p is never "moved".

One of my favorite talks about this subject is Scott Meyers' An Effective C++11/14 Sampler in which he explains how "std::move() doesn't move and std::forward() doesn't forward... they're casts..." ;)

maddouri
  • 3,737
  • 5
  • 29
  • 51
  • _"Pointer[s] are 'like' integers"_ I see what you're trying to do with this analogy but, no, they're not. – Lightness Races in Orbit Oct 17 '15 at 16:35
  • I agree :) It's a somewhat simplistic analogy, yet it helps when thinking about them sometimes. – maddouri Oct 17 '15 at 16:37
  • 2
    Yet, especially when teaching (as you are here), it is potentially harmfully misleading. C++ is very deliberate about creating abstractions, and pointers are one of those. Just because they may be implemented as integers holding memory addresses, doesn't mean they must be. Unless you really need to avoid it, its best to stick to that abstraction. – Lightness Races in Orbit Oct 17 '15 at 16:38