Reputation: 113
The code below is from a game I've written with dynamic memory management. I have a static vector called 'all_gadgets' containing a pointer to every gadget in the game. When a gadget is deleted in runtime, I want to remove the corresponding pointer from the static vector. I've tried this:
Gadget::~Gadget(){
int i = Gadget::all_gadgets.size();
for (std::vector<Gadget *>::iterator it = Gadget::all_gadgets.begin(); it!=all_gadgets.end(); ++it){
if ((*it)==this){
Gadget::all_gadgets.erase(it);
break;
}
}
int j = (i - Gadget::all_gadgets.size());
if(j!=1)
std::cout << j << " ooops! Gadget not deleted!!" << std::endl;
}
In the code above, j will turn out to be zero :( Any suggestions why?
Setting the pointer to null is not an option. I'm using VC10.
Upvotes: 0
Views: 328
Reputation: 283634
Use an invasive double linked-list for this, it will be more efficient for insertion, removal, and in-order iteration.
Normally, linked-lists suffer from poor locality. But with your vector of pointers, while the pointers themselves may be stored with great locality, the content requires an extra level of indirection, and loss of locality.
With an invasive linked list, the locality is exactly as good as the locality of the content. So you achieve the theoretical upper bound for locality, plus cheap insertion and removal.
Your actual problem probably arises from not doing the insertion for every single constructor. The compiler generates a copy constructor (and in C++11, move constructor) by default, which would not update your all_gadgets
list, unless you provide your own.
Upvotes: 2