views:

75

answers:

2

Hello . Suppose I have two containers , holding pointers to objects ,which share some of their elements . from http://www.cplusplus.com/reference/stl/list/erase/ it says that :

This effectively reduces the list size by the number of elements removed, calling each element's destructor before.

How can I remove an object from both containers without calling the destructor twice:

example

#include <map>
#include <string>
using namespace std;
//to lazy to write a class 
struct myObj{
          string pkid;
          string data;
};
map<string,*myObj> container1;
map<string,*myObj> container2;

int main()
{
       myObj * object = new myObj();
       object->pkid="12345";
       object->data="someData";
       container1.insert(object->pkid,object);
       container2.insert(object->pkid,object);

       //removing object from container1
       container1.erase(object->pkid);
       //object descructor been called and container2 now hold invalid pointer

       //this will call try to deallocate an deallocated memory
       container2.erase(object->pkid);

}

please advice

+3  A: 

Use reference counters to determine if all of your containers have deleted your object. Boost has a reference counter class shared_ptr.

http://www.boost.org/doc/libs/1_44_0/libs/smart_ptr/shared_ptr.htm

Starkey
Thanks , I 'll try it .
Alex
+3  A: 

If your containers are holding pointers, then the destructor for those objects won't be called (the STL won't follow those pointers and call the pointee's destructor).

Conversely, if your containers were holding the full-size objects themselves, then the destructor for those objects would be called.

You also had some syntax errors in your map declaration and insert statements. Try running the following code. Notice that the destructor is only called once (for the delete statement). The destructor is never called for the erase statements.

#include <map>
#include <string>
#include <iostream>
using namespace std;
//to lazy to write a class 
struct myObj{
    ~myObj() {
        cout << "DESTRUCTION" << endl;
    }
          string pkid;
          string data;
};
map<string,myObj*> container1;
map<string,myObj*> container2;

int main()
{
       myObj * object = new myObj();
       object->pkid="12345";
       object->data="someData";
       container1.insert(pair<string,myObj*>(object->pkid,object));
       container2.insert(pair<string,myObj*>(object->pkid,object));

       //removing POINTER from container1
       container1.erase(object->pkid);
       //object's destructor has NOT been called yet

       //removing POINTER from container2
       container2.erase(object->pkid);
       //object's destructor STILL hasn't been called

       delete object;   // DESTRUCTION!
}
advait
I see. so in case of pointers , I need to delete them explicitly after pulling them out of all the containers .thanks !
Alex