开发者

C++ Map Gives Bus Error when trying to set a value

开发者 https://www.devze.com 2023-01-05 06:54 出处:网络
I have the following function as the constructor for a class: template<typename T> void Pointer<T>::Pointer(T* inPtr)

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号