
From what I understand order of events is as follows:
1. tu.second resolved (memory accessed) 2. ~test_case() invoked 3. ~test_unit() invoked 4. framework::deregister_test_unit( this ) is invoked 5. map.erase( tu ) 6. free( ptr )
If what you saying is true we perform first step twice. Second time before 6th step. Why would compiler do this?
Because in debug mode the compiler doesn't optimize this access. Maybe it does in release, maybe not. Maybe valgrind would still complain ;-)
Can you test it? just create temp pointer test_unit* tu_ptr = tu.second; before delete.
I had to change the code like this to make it work: // the delete will erase this element from map test_unit* tu_ptr = tu.second; m_test_units.erase( tu.second->p_id ); if( test_id_2_unit_type( tu_ptr->p_id ) == tut_suite ) delete (test_suite const*)tu_ptr; else delete (test_case const*)tu_ptr; and I commented out the deregister_test_unit() code. Or first delete the test_unit then erase tu from the map. I like to destroy objects in the opposite order in which they were created.