0

When swapping or moving an array of objects, what happens if lets say there were pointers pointing to random objects in the array. Does the pointer follow the objects element as they move or not? If they don't, is there a way to make them do so?

schorsch312
  • 5,553
  • 5
  • 28
  • 57
user788888
  • 27
  • 3
  • Nope. They do not – Mad Physicist Apr 13 '21 at 08:30
  • What kind of array? The regular one? The one create with `new`? `std::array`? `std::vector`? – HolyBlackCat Apr 13 '21 at 08:31
  • A pointer refers to an address in memory. If the object moves from that address, the pointer no longer refers to it. The end! If you want reference/pointer/iterator stability while also being able to arbitrarily assort elements, you need to allocate via smart pointer, sort a vector of indices/pointers instead of the objects themselves, or use a container that preserves stability between such operations. There will be plenty info out there on this. – underscore_d Apr 13 '21 at 08:32
  • 1
    @underscore_d I don't agree. Objects cannot be moved in memory. – Daniel Langr Apr 13 '21 at 08:58
  • @DanielLangr Pedantry is only useful if it is accompanied by elaboration... – underscore_d Apr 13 '21 at 09:10
  • @underscore_d Each object has a fixed region of storage during its entire lifetime. For more details, see, e.g., [this question](https://stackoverflow.com/questions/59749312/is-the-value-of-this-pointer-constant-during-the-objects-lifetime). It is about class objects, but the reasoning in the answers applies to all objects in C++. BTW, this is not pedantry, this is a correction of something that is simply not true. – Daniel Langr Apr 13 '21 at 09:14
  • Maybe you want to show some code example and explain how you want it to work. – n. m. could be an AI Apr 13 '21 at 10:18

3 Answers3

2

Objects don't move. The value held in an object can be moved (or swapped or copied) into a different object.

Pointers point to objects. If the value of those objects is changed, the pointer points to the changed value. If the object's lifetime ends, the pointer dangles.

Caleth
  • 52,200
  • 2
  • 44
  • 75
1

When swapping or moving an array of objects , what happens if lets say there were pointers pointing to randomn objects in the array. Does the pointer follow the objects element as they move or not?

The pointer will be pointing to the same memory address as before. If you change the values in the array, that has no effect on the pointer.

If they don't, is there a way to make them do so?

Yes there is a way, you just have to make them point to wherever you want them to point to.

Example:

int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};


int *ptr = &array[5]; // pointing to array[5]
printf("%d\n", *ptr); // prints 6

array[5] = 20;        // changing the value if array[5]
printf("%d\n", *ptr); // still pointing to array[5], prints 20

ptr = &array[2];      // now pointing to array[2]
printf("%d\n", *ptr); // prints 3

This, of course, will have to be applied to the swap method you speak of, of which you show no code and I therefore can't make an example out of.

anastaciu
  • 23,467
  • 7
  • 28
  • 53
0

There are ways to get a pointer to follow an object as it is moved about in an array. The simplest method is to simply modify the pointer as the object is moved within the array.

T arr[5];
T* ptr = &arr[3]; //point to the third element
std::swap(arr[1], arr[3]); //swap array element 1 with 3
ptr = &arr[1]; //update the pointer to point to element 1

What I think you are asking for is to move/swap the object without modifying the pointer to point to the objects new location. The simplest way, and the one that you see the most, is to have an array of pointers to objects allocated on the heap (here achieved using std::shared_ptr).

std::shared_ptr<T> arr[5]; //array of 5 shared_ptr<T>
arr[0] = new T();
arr[1] = new T();
arr[2] = new T();
arr[3] = new T();
arr[4] = new T();
T* ptr = &*arr[3]; //point to the third element
std::swap(arr[1], arr[3]); //swap array element 1 with 3
//no need to update the pointer

This is because shared_ptr allocates T on the heap (hear shown with new operator), so swapping arr[1] and arr[3] means that ptr still points to the same T. NOTE code not compiled or tested.

NOTE this counts for any modifiable contiguous or non contiguous data store such as std::vector<T> instead of an array, for example.

ceorron
  • 1,230
  • 1
  • 17
  • 28
  • `std::optional` [does not allocate on the heap](https://en.cppreference.com/w/cpp/utility/optional): _"If an `optional` contains a value, the value is guaranteed to be allocated as part of the optional object footprint, i.e. no dynamic memory allocation ever takes place."_ You can achieve that with _shared pointers_, but _unique pointers_ will likely be more suitable here due to their lower overhead. – Daniel Langr Apr 13 '21 at 09:30