C++使用 std::set 并出现分段错误 D:
我不知道 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;
}
Event 只是一个简单的结构,有四个参数(时间、发送者、接收者和 ID)。
从我的测试类调用 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 中搞砸了?我以前没用过套装,所以可能是这样吗?我需要初始化一些东西吗?我很困惑...
I have no clue what my error report in valgrind is telling me... but here are the parts of my code pertinent to the issue:
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;
}
Event is just a simple struct which has four parameters (time, sender, receiver and ID).
Calling SendEvent from my test class results in a lovely seg fault... which looks like this (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
Umm... ugly? main.cc:28 is my SendEvent call, a simple:
EventManager::Instance()->DispatchEvent(3, 1, 1, 1);
(It's built as a singleton class, in case you are wondering about the Instance() method).
So that's my problem. I can't make heads or tails of it, but I dunno, am I botching the insert into my std::set? I haven't used sets before, so that might be it? Do I need to initialize something? I'm pretty confused...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在没有看到更多信息的情况下,这是一个猜测!
我猜测您调用
SendEvent
的EventManager
是NULL
。valgrind
错误告诉您 0x10 是 valgrind 不知道的地址,而0x10
是一个很好的整数,可能是结构中的 16 字节偏移量(EventManager
),但您的指针为NULL
。在大多数平台上NULL + 0x10 = 0x10
。这很愚蠢,很容易检查:让程序在
gdb
中出现段错误,跳转到SendEvent
调用的帧,然后查看this
是否为<代码>NULL。Without seeing more info, here's a guess!
I would guess that the
EventManager
you're callingSendEvent
on isNULL
. Thevalgrind
error is telling you that 0x10 is an address that valgrind has no clue about, and0x10
is a nice round number, possibly a 16-byte offset into a structure (EventManager
), but your pointer wasNULL
.NULL + 0x10 = 0x10
on most platforms.This is stupid easy to check: Let the program segfault in
gdb
, jump to the frame of theSendEvent
call, and see ifthis
isNULL
.