C++ priority_queue自定义比较器触发Access violation访问违规问题
问题成因
你只在模板参数中指定了比较器的类型decltype(&CompareEvents),但没有给priority_queue构造函数传入实际的比较器实例。
当使用函数指针作为比较器模板参数时,priority_queue的默认构造函数会将内部存储的比较器初始化为空指针。第一次插入元素时不需要执行比较操作,所以不会触发异常;插入第二个元素时需要调整堆结构,首次调用比较器就会触发空指针访问,也就是你遇到的0地址执行错误。
修复方案
方案1:构造队列时传入函数指针
声明队列时把CompareEvents作为构造参数传入,让内部的比较器指针指向实际的函数实现:
#include "Tryout.h" #include <queue> struct Event { uint64_t mv_timeout; }; bool CompareEvents(const Event& a, const Event& b) { return a.mv_timeout < b.mv_timeout; } int main() { // 构造时传入比较器函数指针 std::priority_queue<Event, std::vector<Event>, decltype(&CompareEvents)> mt_eventQueue(CompareEvents); Event lo_event1{ .mv_timeout = 1, }; Event lo_event2{ .mv_timeout = 2, }; mt_eventQueue.push(lo_event1); mt_eventQueue.push(lo_event2); return 0; }
方案2:改用可默认构造的仿函数作为比较器
把比较器改为仿函数结构体,该类型默认构造即可直接使用,不需要额外传入构造参数,是STL容器更推荐的比较器实现方式:
#include "Tryout.h" #include <queue> struct Event { uint64_t mv_timeout; }; // 定义仿函数比较器 struct CompareEvents { bool operator()(const Event& a, const Event& b) const { return a.mv_timeout < b.mv_timeout; } }; int main() { // 直接用仿函数作为模板参数,不需要传入构造参数 std::priority_queue<Event, std::vector<Event>, CompareEvents> mt_eventQueue; Event lo_event1{ .mv_timeout = 1, }; Event lo_event2{ .mv_timeout = 2, }; mt_eventQueue.push(lo_event1); mt_eventQueue.push(lo_event2); return 0; }
内容的提问来源于stack exchange,提问作者user2089648
相关产品推荐
相关产品推荐

