A few months ago, i got an issue with my code when i switched it from windows to Linux. On my STL containers, a call to clear() for exemple on an empty container crashed my program. To prevent that, i had to add a (size()>0) test before each "dangerous" access, and assumed that this was due to the implementation of STL on Linux.
Today, i got the same problem on Windows (VC++2005) for one of my containers.
The following code triggers it (NameMap is a std::map<std::string,Equipment*>) :
As the others have said, a call to clear() on an empty container will not cause a program to crash. Something else is causing your program to crash and the call to clear() is just triggering it.
The crash is an access violation at adress 0. For the line for(NameMap::iterator it = nameMap.begin(); it!=nameMap.end(); ++it){,
It occurs in iterator _xtree::begin()
/**
* Descripteur d'un equipement
*/
typedefstruct Equipment{
staticconst std::string NODENAME;
//Nom del'equipement
std::string name;
//other members...
//.....
//construction depuis un noeud xml
Equipment(const TiXmlElement * RESTRICT);
class Store{
public:
staticconst std::string const NODENAME;
const Store& operator =(const TiXmlElement * RESTRICT);
~Store();
/**
* Container pour acces par nom
*/
typedef std::map<std::string, Equipment*> NameMap;
static Equipment::NameMap nameMap;
private:
void clear();
};
static Store store;
}Equipment;
For now, i don't fill the map, so the crash occurs when i exit, at the liberation of the allocated Equipment(s) in Equipment::Store::clear(), called in Equipment::Store destructor
Another detail. in my assignment operator for Equipment::Store, i call Equipment::Store::clear() before trying to load from my xml file, and it doesn't crash,with the map also empty.
So this must be a destruction order issue with my static data somewhere. If i remove the static keyword for nameMap, i don't seem to have the problem anymore.
Can a static member of a class (the map in Store) be destroyed before a static object of the class (the Store)? That seems strange
I allocate Equipments in Store constructor, store their pointers in the map, and free them in store::clear(), which is called at the start of Store's assignmeent operator and in it's destructor.
Actually, i keep pointers due to some previous behaviour of the code. I could store Equipment directly in my map and not worry about allocation and liberation.
Why not shared_ptr? Because i don't know everything yet, but i'll add that to my "to study" list :)
About the use of static objects, for lots of data types i defined, i have only one container of this type in the whole application, so i like to allocate the container as a static member of the contained object.
I used to do
You may be invoking a copy constructor or assignment operator on your Equipment or Store class. Try making the copy constructor and assignment operator for both classes private and see if that gives you any hints. If it no longer compiles, it a good indication you were calling delete on the same pointer twice.
Non-const class static and global data are a strong code smell, indicative of bad design. They are functionally equivalent; the static member data is just encapsulated in a class namespace.
Use a singleton if you must, but this is not a case where a singleton should be necessary. Are you just trying to avoid passing the object around?