【发布时间】:2015-01-15 13:50:16
【问题描述】:
我收到消息“VS 已触发断点”的问题,当我在那里中断时,VS 跳转到 POCO NotificationCenter 的源代码:
我正在使用 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::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;
}
}
这个类的其余方法只是getter/setter。
知道为什么会这样吗?
我的研究告诉我,如果堆被破坏,就会出现此消息。但我找不到任何应该发生这种情况的代码行。 这种行为有点奇怪,因为当我在消息上按继续时,应用程序运行没有任何问题。当应用程序没有在后台使用调试器启动时,我没有任何问题(例如,在 Debug 文件夹中启动 exe)。
我仍在学习 C++,因此非常感谢任何反馈/帮助。
谢谢
【问题讨论】:
-
由于它发生在
ObserverList复制构造上,并且由于ObserverList是智能指针std::vector的类型定义(这应该很安全),我怀疑堆粉碎。这意味着您在堆上的另一个对象的边界之外写入,而该对象恰好位于内存中被粉碎对象的正前方(您是否使用任何持有本地缓冲区的对象?char[],也许?)或通过无效恰好指向不幸对象的指针。删除后使用某些内容是获得该内容的好方法。当然,这都是猜测。 -
获取 Microsoft Application Verifier 并启用堆检查以查看您是否损坏了明显的内容。
-
我无法找出 Microsoft Application Verifier 的任何问题 - 日志总是提到零错误和零警告。
-
不——没有本地缓冲区——恐怕。但很明显,问题与“notification = receivedMessagesQueue.waitDequeueNotification();”行有关。重新启动后,我不再得到 VS 描述的异常。现在,每次有新通知可用时,我都会收到通知变量地址的写访问冲突。这对我来说没有意义?!?
标签: c++ visual-c++ poco-libraries