C ++, используя std :: set и получая ошибку сегментации D: - PullRequest
0 голосов
/ 19 октября 2011

Я понятия не имею, о чем говорит мой отчет об ошибках в valgrind ... но вот части моего кода, относящиеся к проблеме:

template<typename T>
struct CompareEvents {
public:
    bool operator()(const T a, const T b) const {
        return a.time < b.time ? true : false;
    } 
};


class EventManager {
public:
    void EventManager::SendEvent(int delay, size_t sender, size_t receiver, size_t eventId) {
        if (delay > 0) {
            eventQueue.insert(Event((GetTime() + delay), sender, receiver, eventId));  //line 55
        }
    }
private:
    std::set<Event, CompareEvents<Event>> eventQueue;
}

Событие - это простая структура, которая имеет четыре параметра (время, отправитель, получатель и идентификатор).

Вызов SendEvent из моего тестового класса приводит к прекрасной ошибке сегмента ... которая выглядит следующим образом (valgrind):

==998== Invalid read of size 8
==998==    at 0x40D544: std::_Rb_tree<Event, Event, std::_Identity<Event>, CompareEvents<Event>, std::allocator<Event> >::_M_begin() (stl_tree.h:493)
==998==    by 0x40D8C4: std::pair<std::_Rb_tree_iterator<Event>, bool> std::_Rb_tree<Event, Event, std::_Identity<Event>, CompareEvents<Event>, std::allocator<Event> >::_M_insert_unique<Event>(Event&&) (stl_tree.h:1261)
==998==    by 0x40C44B: std::__cxx1998::set<Event, CompareEvents<Event>, std::allocator<Event> >::insert(Event&&) (stl_set.h:419)
==998==    by 0x40ADE2: std::__debug::set<Event, CompareEvents<Event>, std::allocator<Event> >::insert(Event&&) (set.h:210)
==998==    by 0x40A130: EventManager::SendEvent(int, unsigned long, unsigned long, unsigned long) (EventManager.cc:55)
==998==    by 0x402D07: main (main.cc:28)
==998==  Address 0x10 is not stack'd, malloc'd or (recently) free'd

Ммм ... некрасиво? main.cc:28 - это мой вызов SendEvent, простой:

EventManager::Instance()->DispatchEvent(3, 1, 1, 1);

(Он построен как одноэлементный класс на случай, если вас интересует метод Instance ()).

Так что это моя проблема. Я не могу сделать из этого ни головы, ни хвоста, но я не знаю, испортил ли я вставку в мой std :: set? Я не использовал наборы раньше, так что это может быть? Нужно ли что-то инициализировать? Я в замешательстве ...

1 Ответ

5 голосов
/ 19 октября 2011

Не видя больше информации, вот предположение!

Я бы предположил, что EventManager, на который вы звоните SendEvent, это NULL. Ошибка valgrind говорит вам, что 0x10 - это адрес, о котором valgrind понятия не имеет, а 0x10 - это хорошее круглое число, возможно 16-байтовое смещение в структуре (EventManager), но ваш указатель был NULL. NULL + 0x10 = 0x10 на большинстве платформ.

Это глупо легко проверить: разрешить программе segfault в gdb, перейти к кадру вызова SendEvent и посмотреть, является ли this NULL.

...