尝试设置值时,C ++ Map出现总线错误

时间:2010-06-29 14:23:30

标签: c++ data-structures

我有以下函数作为类的构造函数:

template<typename T>
void Pointer<T>::Pointer(T* inPtr)
{
  mPtr = inPtr;
  if (sRefCountMap.find(mPtr) == sRefCountMap.end()) {  
    sRefCountMap[mPtr] = 1;
  } else {
    sRefCountMap[mPtr]++;
  }
}

以下是地图的定义:

static std::map<T*, int> sRefCountMap;

运行此代码时,有时会出现总线错误:

#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

感谢。

2 个答案:

答案 0 :(得分:6)

根据您的评论,您说您正在初始化静态Pointer。这很可能意味着你遇到了“静态初始化命令惨败” - 如果两个静态对象在不同的​​编译单元中,那么它没有定义它们初始化的顺序。所以如果一个的构造函数依赖于另一个已经存在初始化,然后你可能会逃避它,或者你可能不会。 Sod's Law规定代码在测试期间会起作用,然后在部署时神秘地破解。

最好的解决方案是避免静态物体;他们很少是个好主意。

另一种可能性是懒惰的实例化,如下所示:

typedef std::map<T*, int> RefCountMap;

static RefCountMap& GetRefCountMap()
{
    static RefCountMap map;
    return map;
}

这可能有它自己的问题;它保证在它被使用之前被构造,但是在你完成它之前可能会被破坏,如果静态析构函数访问它,并且可能存在线程安全问题。有关血淋淋的细节,请参阅有关Singleton模式的许多讨论,这需要一个静态实例。 C ++中的单身人士是痛苦的整个世界,如果可能的话,最好避免使用。

答案 1 :(得分:1)

您的程序中的其他位置可能已损坏您的堆。通过内存调试器(例如valgrind)运行程序,找出发生损坏的位置。