Карта C ++ дает ошибку шины при попытке установить значение - PullRequest
5 голосов
/ 29 июня 2010

У меня есть следующая функция в качестве конструктора для класса:

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 ]

6 голосов
/ 29 июня 2010

Из ваших комментариев вы говорите, что инициализируете статический Pointer.Скорее всего, это означает, что вы столкнулись с «фиаско статического порядка инициализации» - если два статических объекта находятся в разных единицах компиляции, то не определено, в каком порядке они инициализируются. Поэтому, если конструктор одного зависит от другого, уже существующегоинициализируется, тогда вам может это сойти с рук, а может и нет.Закон Сода гласит, что код будет работать во время тестирования, а затем загадочно ломаться при развертывании.

Лучшее решение - избегать статических объектов;они редко бывают хорошей идеей.

Другая возможность - это ленивый экземпляр, что-то вроде этого:

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

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

Это может иметь свои собственные проблемы;он гарантированно будет создан до его использования, но может быть уничтожен до того, как вы закончите с ним, если статический деструктор получит к нему доступ, и могут возникнуть проблемы с безопасностью потоков.Чтобы узнать подробности, смотрите множество обсуждений паттерна Singleton, который требует статического экземпляра.Синглеты в C ++ - это целый мир боли, лучше избегать их, если это возможно.

1 голос
/ 29 июня 2010

Вы, вероятно, повредили свою кучу где-то еще в вашей программе.Запустите вашу программу через отладчик памяти (например, valgrind) и выясните, где происходит повреждение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...