Nolf
Nolf

Reputation: 113

erasing a pointer to an element in a static vector, in the element's own destructor

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

Answers (1)

Ben Voigt
Ben Voigt

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

Related Questions