2015-01-15 1 views
2

я проблема, что я получаю сообщение «VS вызвало точку останова», и когда я нарушу там, VS прыжки в исходный код POCO NotificationCenter: enter image description hereвизуальная студия вызвало точку останова Poco NotificationCenter

I пользуюсь Poco 1.5.4.

Предыдущая запись в стеке вызовов находится в следующем фрагменте коды:

void WebSocketController::HandleReceivedMessages() { 
    AutoPtr<Notification> notification(receivedMessagesQueue.waitDequeueNotification()); 

    while (!messageHandlerActivity.isStopped() && notification) { 
     MessageNotification* messageNotification = dynamic_cast<MessageNotification*>(notification.get()); 
     if (messageNotification) 
     { 
      notificationCenter.postNotification(messageNotification); 
     } 

     notification = receivedMessagesQueue.waitDequeueNotification(); 
    } 
} 

бетона линии я могу увидеть в стеке вызовов (с номером строки) заключается в следующем:

notification = receivedMessagesQueue.waitDequeueNotification(); 

Это код MessageNotification.h:

class MessageNotification : public Notification 
    { 
    public: 
     MessageNotification(Message *data); 
     ~MessageNotification(); 
     Message* GetData(); 
    private: 
     Message *data; 
    }; 

Это код MessageNotification.cpp:

MessageNotification::MessageNotification(Message *data) { 
     this->data = data; 
    } 

    MessageNotification::~MessageNotification() { 
     delete data; 
     data = nullptr; 
    } 

    Message* MessageNotification::GetData() { 
     return data; 
    } 

И здесь вы можете увидеть конструкторы класса сообщений:

 Message::Message(const MessageCommandEnum cmd, const string& to, StringMap *params, const string& data) 
      : cmd(cmd), to(to), data(data) { 
      this->params = params == nullptr ? new StringMap() : params; 
     } 

     Message::Message(const Message& msg) : to(msg.to), cmd(msg.cmd), data(msg.data) { 
      params = new StringMap(*msg.params); 
     } 

     Message::Message(const Message* msg) : to(msg->to), cmd(msg->cmd), data(msg->data) { 
      params = new StringMap(*msg->params); 
     } 

     Message::~Message() { 
      if (params != nullptr) { 
       delete params; 
       params = nullptr; 
      } 
     } 

Остальные методы в этом классе только геттеры/сеттеры.

Любая идея, почему это происходит?

Мои исследования сказали мне, что это сообщение возникает, если куча разрушается. Но я не могу найти ни одной строки кода, где это должно произойти. Поведение немного странно, поскольку, когда я нажимаю кнопку «Продолжить» в сообщении, приложения запускаются без каких-либо проблем. У меня нет проблем, когда приложение не запускается с отладчиком в фоновом режиме (например, запустите exe в папке Debug).

Я все еще изучаю C++, поэтому я действительно ценю любую обратную связь/помощь.

Благодаря

+0

Поскольку это происходит при построении копии 'ObserverList', и поскольку' ObserverList' является typedef для 'std :: vector' интеллектуальных указателей (это должно быть довольно безопасно), я подозреваю, что куча разбита. Это означает, что вы написали за пределами другого объекта в куче, который только что лежал непосредственно перед разбитым объектом в памяти (вы работаете с любыми объектами, в которых хранится локальный буфер?] [Char [] ', возможно?) Или через неверный указатель, который только что указывал на несчастливый объект. Использование чего-то после его удаления - хороший способ получить это.Конечно, это все догадки. – Wintermute

+0

Получить Microsoft Application Verifier и включить проверку кучи, чтобы убедиться, что вы испортили что-то очевидное. – Samuel

+0

Я не мог понять никаких проблем с Microsoft Application Verifier - журнал всегда упоминает нулевые ошибки и нулевые предупреждения. – Skully

ответ

2

AutoPtr уведомление в WebSocketController :: HandleReceivedMessages() будут удалены AutoPtr как только вы назначить другой указатель на него. Однако в этот момент указатель был передан NotificationCenter в другой AutoPtr, и где бы вы ни пытались разыменовать (или AutoPtr пытается удалить), это приведет к неопределенному поведению.

После того, как вы указали указатель уведомления в AutoPtr, просто передайте его как AutoPtr (передайте его с уведомлением.cast <MessageNotification>()). Кроме того, аргумент указателя конструктора MessageNotification никогда не передается, потому что вы никогда не создаете объект MessageNotification (вы просто динамически добавляете уведомление * в MessageNotification *).

Посмотрите на NotificationQueue example, чтобы понять, как это сделать надлежащим образом.

+0

Привет, Алекс! Спасибо за вашу помощь. Я попробую немедленно. Большое спасибо! – Skully

+1

Хорошо, глядя на мой комментарий о аргументе конструктора MessageNotification, я подумал, что вы, вероятно, передаете его в другом месте, чтобы вы могли его игнорировать. Как правило, никогда не смешивайте AutoPtr с голыми указателями. Если вы абсолютно должны назначить AutoPtr указателю, убедитесь, что вы вызываете duplicate()/release() вручную (т. Е. Никогда не вызывайте delete в указателе, который был обернут в AutoPtr в любой точке). – Alex

+0

И, глядя на код, кажется, что вы используете ручную блокировку()/unlock(), что небезопасно. Используйте ScopedLock, как рекомендовано в [этом ответе] (http://stackoverflow.com/questions/27851837/linearhashtable-iter-not-dereferencable-and-iter-not). Кстати, вы можете принять ответ? Благодарю. – Alex

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