struct object_t
{
int n;
// ...
};
struct action_t
{
// ...
};
struct pair_t
{
vector<action_t> actions;
object_t *object; // points to data[something]
};
vector<object_t> objects;
vector<pair_t> data;
//
// Removes an entry from 'vector<pair_t> data' if pairt_t::object doesn't point to any of 'vector<object_t> objects' objects
//
//EDIT: This function should erase invalid elements from data vector
// but it doesn't work (my brain too)
void sync_vectors()
{
bool found=false;
for(int i=0;i<data.size();i++)
{
for(int j=0;j<objects.size();j++)
{
if(data[i].object==&objects.at(j)); // compare adrsseses
found=true;
}
if(found==false)
{
data.erase(data.begin()+i);
}
else found=false;
}
}
int main()
{
for(int i=0;i<10;i++)
{
object_t tmp;
tmp.n=i;
objects.push_back(tmp);
pair_t ptmp;
ptmp.object=&objects[i];
data.push_back(ptmp);
}
objects.erase(objects.begin()+5);
sync_vectors();
for(int i=0;i<data.size();i++)
cout <<data[i].object->n<<endl;
}
So I have two vectors 'objects' and 'data'. First I create the 'objects' vector. The I create 'data' vector, which keeps pointers to 'objects' vector. At some specific moment I want to access objects from data. But the problem is that sometimes I need to erase some elements from 'objects' and then 'data_t::object' points to deleted objects.
Why do you need a vector of pointers that point to the objects stored in a different vector? Is it to keep them in a specific order without re-sorting the vector?
If you can obtain the element that holds the pointer to the object you need to free using the pointer vector sorting criterion, you can use a binary search to find it. Otherwise, you'll have to use a linear search each time you want to erase an element.
I think the problem with sync_vectors is that you look at a position, say '4', and if not found in the objects vector, you erase the entry at position 4. This causes everything in subsequent positions to shift down (position 5->4, 6->5, etc). Then you increment i to point to '5', thereby never checking the object that is now at position 4. The solution is to move the 'i++' to the 'else' block.
Of course, This isn't quite an optimal solution, and given a large enough data set, could be time consuming. It's an interesting problem - I would think a solution might be to have the object wrapped in some sort of custom smart pointer that keeps track of other vectors referencing it. Then it could delete from those vectors when the object is deleted. But for your purposes may be overkill, if it would even work :)
If you do insist on implementing your own solution, like above, consider at least encapsulating the internals in a class and providing an interface to the user. That way you can enforce invariants.