C++ STL map issue

Apr 27, 2009 at 12:23pm
Which is the safe way to delete a newed pointer on map??

int main()
{
map<int,A*> aMap;


A* o1= new A();
A* o2= new A();
A* o3= new A();
A* o4= new A();
A* o5= new A();

aMap.insert(make_pair(1,o1));
aMap.insert(make_pair(2,o2));
aMap.insert(make_pair(3,o3));
aMap.insert(make_pair(4,o4));
aMap.insert(make_pair(5,o5));

aMap.erase(1);
delete o1;
o1 = NULL; // is this safe way?? would this cause any problem in multithreaded applications??

// or follwoing one is the safe way??

delete o1;
o1 = NULL;
aMap.erase(1);


cout<<"Delete success";

return 0;

}

Thanks in advance
Last edited on Apr 27, 2009 at 12:23pm
Apr 27, 2009 at 12:42pm
At some convenient time, traverse the map (with an iterator), delete the second value, and almost certainly you may want to clear the map.
Apr 27, 2009 at 1:02pm
both ways can be used to delete a pointer on map, but which is the safe way??
Apr 27, 2009 at 1:18pm
It's not one or the other, it's both.
Apr 27, 2009 at 1:27pm
you mean both r safe???
Last edited on Apr 27, 2009 at 2:24pm
Apr 27, 2009 at 2:17pm
No. The first (deleting entries) frees the entires back to the heap, the second (clearing the map) releases dangling references to the heap. Again, you need to do both.
Apr 27, 2009 at 2:25pm

approach #1

aMap.erase(1);
delete o1;
o1 = NULL; // is this safe way?? would this cause any problem in multithreaded applications??

approach #2

delete o1;
o1 = NULL;
aMap.erase(1);


now tel me which is safe??
Apr 27, 2009 at 3:17pm
looks both of ways are safe because when you insert a pair to a map, map will make a copy (or copy construct if any elment of pair is a C++ object ) of pair.

But, you MUST replace

1
2
3
delete o1;
o1 = NULL;
aMap.erase(1);


with

1
2
3
4
5
6
if (o1)
{ 
  delete o1;
  o1 = NULL;
}
aMap.erase(1);


because, your new operation may fail.


and you must make the whole operation atomic such as puts mutex around it if more than one thread can run this operation.


Last edited on Apr 27, 2009 at 3:25pm
Apr 27, 2009 at 3:28pm
I don't think so. Are you sure about that?
Apr 27, 2009 at 3:45pm
binaryboy is right. If this is a multi-threaded app, you must put a mutex around just about anything involving STL containers. Thread-safety in C++ is very implementation specific.

A more important point is that pointers are rather unsafe (hard to manage) in a threaded environment. Use copies or use a thread-safe shared pointer. Here's why: in a threaded environment, you have to make sure that no object is deleted while any thread has a pointer to that object. You need to protect each object with a lock to ensure the object the pointer points to is not deleted from under you. It doesn't matter which option you choose if another thread is using the pointer when the delete is called. Often a copy is cheaper than managing locks.
Apr 27, 2009 at 4:06pm
There was no mention of an MT environment, that's a different issue.

You don't neet to check for NULL on delete/free.
Apr 28, 2009 at 4:31am
Mutex locks are in place already since our application runs in solaris multithreaded enironment.
NULL checks are also taken care, but if use the approach #1

i.e.,

approach #1

aMap.erase(1);
delete o1;
o1 = NULL;

its crashing at "delete o1" ... see the stack trace for the same

ffffffff6f2d40a4 _lwp_kill (6, 0, ffffffff6f3f7338, ffffffffffffffff, ffffffff6f3ec000, 0) + 8
ffffffff6f24a68c abort (1, 1b8, ffffffff6f50786c, 1a1a80, 0, 0) + 118
ffffffff7d900d54 free (25bb18f20, 25bb2a720, 8, ffffffff733e30dc, 1, 25bb18f91) + 1f4
ffffffff6f50786c __1c2k6Fpv_v_ (25bb2a720, 25bb2a720, 25bb2a720, 25bb2a720, 40, 0) + 4
ffffffff733e30dc __1cFpdfcoMCCoSession2T6M_v_ (2e020, 259171ce0, 8, 40, ffffffff73e60bb8, 259171e50) + e74
ffffffff733f8a80 __SLIP.DELETER__P (259171ce0, 1, ffffffff73e60cc7, ffffffff733f8a78, ffffffff73e60cc0, ffffffff733f8a78) +

I'm not seeing any issues with the approach #2
i.e.,

delete o1;
o1 = NULL;
aMap.erase(1);




Apr 28, 2009 at 6:39am
Sorry, you don't neek check for NULL on delete. kbw is right,

but, on my machine:

approach #1
1
2
3
aMap.erase(1);
delete o1;
o1 = NULL; 


it's safe.

My environment is Windows XP-x64 sp2 + Viual Studio 2005 SP1 + Intel PD 920.

so, I think STL implementation maybe different on different platforms...
Apr 28, 2009 at 7:26am
not sure , but mine is Solaris 10 and UltraSPARC(T2000 and higher versions)
Apr 28, 2009 at 8:04am
erase takes an iterator. The code is:
1
2
3
for (p = mymap.begin(); p != mymap.end(); ++p)
    delete p->second;
mymap.clear();


But you shouldn't be able to pass an integer to erase.
Topic archived. No new replies allowed.