2010-06-29 36 views
5

tôi có chức năng sau khi các nhà xây dựng cho một lớp:C++ Map Cho Xe Buýt báo lỗi khi cố gắng thiết lập một giá trị

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

Dưới đây là định nghĩa cho bản đồ:

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

tôi nhận được Đôi khi xảy ra lỗi khi mã này chạy:

#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 

Cảm ơn.

+4

tại sao không chỉ làm sRefCountMap [mPtr] ++? Nếu nó không tồn tại, nó sẽ được đưa vào cuộc sống ban đầu thành 0 ... – Goz

+2

Bạn có bất kỳ trường hợp tĩnh nào của 'Con trỏ' không? Chúng có thể được xây dựng trước bản đồ. –

+1

Đây có phải là chương trình đơn luồng hay làm một số chủ đề khác nhau sử dụng sRefCountMap không? Chỉ cần tự hỏi nếu chúng ta có thể loại trừ lỗi chủ đề. –

Trả lời

6

Từ nhận xét của bạn, bạn nói rằng bạn đang khởi tạo static Pointer. Điều này rất có thể có nghĩa là bạn đã gặp phải "fiasco thứ tự khởi tạo tĩnh" - nếu hai đối tượng tĩnh nằm trong các đơn vị biên dịch khác nhau, thì nó không được định nghĩa thứ tự mà chúng được khởi tạo. Vì vậy, nếu hàm tạo của một phụ thuộc vào khởi tạo, sau đó bạn có thể nhận được đi với nó, hoặc bạn có thể không. Luật Sod ra lệnh rằng mã sẽ hoạt động trong quá trình thử nghiệm, sau đó phá vỡ một cách bí ẩn khi nó được triển khai.

Giải pháp tốt nhất là tránh các vật thể tĩnh; chúng hiếm khi là một ý tưởng hay.

Một khả năng khác là instantiation lười biếng, cái gì đó như thế này:

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

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

Điều này có thể có những vấn đề của riêng của nó; nó được đảm bảo được xây dựng trước khi nó được sử dụng, nhưng có thể bị phá hủy trước khi bạn kết thúc với nó, nếu một destructor tĩnh truy cập nó, và có thể có các vấn đề an toàn luồng. Đối với các chi tiết đẫm máu, hãy xem nhiều cuộc thảo luận về mẫu Singleton, yêu cầu một cá thể tĩnh. Singletons trong C++ là cả một thế giới đau đớn, tránh né tốt nhất nếu có thể.

+0

FWIW, đó chỉ là một biến toàn cầu tốt đẹp, không phải là một singleton (bạn không ngăn cản việc tạo ra thêm 'RefCountMap'). Tuy nhiên, tôi nghĩ rằng giải pháp toàn cầu này là cao hơn nhiều so với một singleton. – GManNickG

+0

@GMan: bạn nói đúng; Tôi đã chỉnh sửa để cải thiện thuật ngữ. –

1

Bạn có thể đã làm hỏng vùng lưu trữ của bạn ở một nơi khác trong chương trình của bạn. Chạy chương trình của bạn thông qua trình gỡ rối bộ nhớ (ví dụ: valgrind) và tìm ra nơi xảy ra sự cố.

+3

Câu trả lời của Mike có nhiều khả năng bây giờ bạn đã nói đó là một 'Con trỏ 'tĩnh. Tuy nhiên, khi không có khởi tạo tĩnh, một sự cố bí ẩn trong một lớp hoặc hàm thư viện chuẩn gần như luôn luôn là một vấn đề tham nhũng heap. –

Các vấn đề liên quan