2010-06-29 3 views
5

У меня есть следующая функция как конструктор для класса:C++ Карта дает Bus Error при попытке установить значение

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; 

Я получаю a Ошибка шины иногда, когда этот код запускается:

#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, [email protected]) 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}, [email protected]) 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}, [email protected]) 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, [email protected]) at stl_map.h:339 

Спасибо.

+4

Почему бы не просто сделать sRefCountMap [mPtr] ++? Если он не существует, он будет приведен в действие инициализированным до 0 ... – Goz

+2

Есть ли у вас какие-либо статические экземпляры 'Pointer'? Они могут быть построены до карты. –

+1

Является ли эта программа одиночной, или несколько разных потоков используют sRefCountMap? Просто интересно, можем ли мы исключить ошибки потоков. –

ответ

6

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

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

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

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

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

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

+0

FWIW, это просто хорошая глобальная переменная, а не синглтон (вы не мешаете созданию дальнейших 'RefCountMap'). Однако я считаю, что это глобальное решение намного превосходит одноэлементное. – GManNickG

+0

@GMan: вы правы; Я отредактировал, чтобы улучшить терминологию. –

1

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

+3

Ответ Майка, скорее всего, теперь, когда вы сказали, что это статический «Указатель». Однако, если статическая инициализация не задействована, таинственный сбой в стандартном классе или функции библиотеки почти всегда является проблемой кучи. –

Смежные вопросы