C++使用 std::set 并出现分段错误 D:

发布于 2024-12-10 19:36:42 字数 2002 浏览 0 评论 0原文

我不知道 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

强者自强 2024-12-17 19:36:42

在没有看到更多信息的情况下,这是一个猜测!

我猜测您调用 SendEventEventManagerNULLvalgrind 错误告诉您 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 calling SendEvent on is NULL. The valgrind error is telling you that 0x10 is an address that valgrind has no clue about, and 0x10 is a nice round number, possibly a 16-byte offset into a structure (EventManager), but your pointer was NULL. NULL + 0x10 = 0x10 on most platforms.

This is stupid easy to check: Let the program segfault in gdb, jump to the frame of the SendEvent call, and see if this is NULL.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文