Reputation: 45
Let's say I define the following struct:
struct dockPose {
Complex* pose;
int Cluster;
struct dockPose* DP;
float Distance;
int Density;
};
typedef struct dockPose DockPose;
Then, I declare a vector which will be sorted by Density value using the std::sort() function. After the call to std::sort, will my DockPose* DP pointers still point to the same DockPose instance it was pointing before? If not, what can I do to be sure DP pointers points to the same DockPose it was pointing to before sorting (if there is anything I can do) ?
Upvotes: 1
Views: 974
Reputation: 103733
Yes, the pointers will still point to the same instance. But that may not be what you actually want. When you call std::sort
on a vector, it does not change the location of instances (that's not even a thing you can do in C++). It swaps their values with each other. This is probably better explained with a simplified example. Take this struct:
struct Foo
{
int x;
Foo* buddy;
};
bool operator<(Foo const& lhs, Foo const& rhs)
{
return lhs.x < rhs.x;
}
Now, lets say I make a vector of these, with decreasing x values, and each one having a pointer to the one that comes after it (and the last having a pointer to the first):
std::vector<Foo> vec(5);
for (int i = 0; i < 5; ++i)
{
vec[i].x = 4 - i;
vec[i].buddy = &vec[(i + 1) % 5];
}
Now, if I sort this vector, it is essentially going to reverse. But the instances themselves don't change their location. Instead, their values change such that the first one has the lowest x
value, and it increases from there. Now, the pointer member changes along with the x
value.
So take, for example, vec[0]
, which had an x
value of 4, and a pointer to vec[1]
(which has an x
value of 3). After the sort, those values will end up in the last element, vec[4]
. So vec[4]
will have an x
value of 4, and a pointer to vec[1]
(which, after the sort, has an x
value of 1).
So, before the sort, the element with the x
value 4, had a pointer to the element with an x
value of 3. After the sort, the element with the x
value of 4 has a pointer to the element with the x
value of 1. I doubt this is what you wanted.
Since you are interested in the identity of the instances, not just their values, you should probably be using something like std::vector<std::unique_ptr<dockPose>>
. For my Foo
example, I could do something like this:
std::vector<std::unique_ptr<Foo>> vec;
for (int i = 0; i < 5; ++i)
vec.emplace_back(new Foo);
for (int i = 0; i < 5; ++i)
{
vec[i]->x = 4 - i;
vec[i]->buddy = vec[(i + 1) % 5].get();
}
Note that when you do this, you need to use a different comparison function. One which compares the dereferenced pointers, rather than the pointers themselves.
Upvotes: 3
Reputation: 341
keeping pointers to objects in a vector is not a good idea. Even a simple push_back() could make all of your pointers invalid, if you happen to cause a resize. If you want to keep pointers to objects in a container you would be better to use a std::list
Upvotes: 0
Reputation: 18974
If you have a vector of DockPose
objects you are treating them as values, in which case it's a bad idea to keep pointers to them. I suspect you actually want them to be entities (two entities are distinct even if they have identical values).
In which case you should instead have a vector of pointers to the entities; sorting the vector of pointers will then not invalidate your DP
pointers.
Upvotes: 0
Reputation: 720
Sorting will not change the values of those pointers. Pointers are simply variables holding memory addresses, sorting a vector will not change any of the member variable data of the objects in the vector.
Upvotes: 0
Reputation: 56567
std::sort
will just move the objects around in the vector, but the pointers themselves will still point to the same memory location they pointed initially.
Upvotes: 0