I have the following function as the constructor for a class:
template<typename T>
void Pointer<T>::Pointer(T* inPtr)
{
mPtr = inPtr;
if (sRefCountMap.find(mPtr) == sRefCountMap.end()) {
sRefCountMap[mPtr] = 1;
} else {
sRefCountMap[mPtr]++;
}
}
Here is the definition for the map:
static std::map<T*, int> sRefCountMap;
I get a Bus Error sometimes when this code is run:
#0 0x95110fc0 in std::_Rb_tree_decrement ()
#1 0x00017ccc in std::_Rb_tree_iterator<std::pair<Language::Value* const, int> >::operator-- (this=0xbfffe014) at stl_tree.h:196
#2 0x0001b16c in std::_Rb_tree<Language::Value*, std::pair<Language::Value* const, int>, std::_Select1st<std::pair<Language::Value* const, int> >, std::less<Language::Value*>, std::allocator<std::pair<Language::Value* const, int> > >::insert_unique (this=0x2a404, __v=@0xbfffe14c) at stl_tree.h:885
#3 0x0001b39c in std::_Rb_tree<Language::Value*, std::pair<Language::Value* const, int>, std::_Select1st<std::pair<Language::Value* const, int> >, std::less<Language::Value*>, std::allocator<std::pair<Language::Value* const, int> > >::insert_unique (this=0x2a404, __position={_M_node = 0x2a408}, __v=@0xbfffe14c) at stl_tree.h:905
#4 0x0001b5a0 in __gnu_norm::map<Language::Value*, int, std::less<Language::Value*>, std::allocator<std::pair<Language::Value* const, int> > >::insert (this=0x2a404, position={_M_node = 0x2a408}, __x=@0xbfffe14c) at stl_map.h:384
#5 0x0001b6e0 in __gnu_norm::map<Language::Value*, int, std::less<Language::Value*>, std::allocator<std::pair<Language::Value* const, int> > >::operator[] (this=0x2a404, __k=@0x2e110) at stl_map.h:339
Thanks.
From your comments, you say that you're initialising a static Pointer
. This most likely means you've encountered the "static initialisation order fiasco" - if two static objects are in different compilation units, then it's not defined which order they're initialised in. So if the constructor of one depends on the other already being initialised, then you might get away with it, or you might not. Sod's Law dictates that the code will work during testing, then mysteriously break when it's deployed.
The best solution is to avoid static objects; they're rarely a good idea.
Another possibility is lazy instantiation, something like this:
typedef std::map<T*, int> RefCountMap;
static RefCountMap& GetRefCountMap()
{
static RefCountMap map;
return map;
}
This may have issues of it's own; it's guaranteed to be constructed before it's used, but might be destroyed before you've finished with it, if a static destructor accesses it, and there may be thread safety issues. For the gory details, see the many discussions on the Singleton pattern, which requires a static instance. Singletons in C++ are a whole world of pain, best avoided if possible.
You have likely corrupted your heap somewhere else in your program. Run your program through a memory debugger (e.g. valgrind) and figure out where the corruption is occurring.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With