【问题标题】:Segmentation fault in std::map::insert(...)std::map::insert(...) 中的分段错误
【发布时间】:2011-04-07 03:46:21
【问题描述】:

我用过搜索,但没有找到让我满意的答案...所以..这是一段代码:

 //VoteContainer.h    
    typedef uint32_t order_id_t;
    typedef int driver_id_t;

    class Vote {

        public:
            enum DriverVoteResponse {YES, NO, TIMEOUT};

            struct DriverResponse {
                driver_id_t driver_id;
                time_t time;
                DriverVoteResponse response;
            };

            Vote() : m_order_id(0), m_time_until(0) {};
            Vote(order_id_t inOrderId, std::vector<driver_id_t> inPermittedDrivers, int inSeconds);
            Vote(const Vote & other) : m_order_id(other.m_order_id), m_time_until(other.m_order_id) {
                m_drivers_responses = other.m_drivers_responses;
                m_permitted_drivers = other.m_permitted_drivers;
            };

            virtual ~Vote() {};

            virtual void addDriverVote(driver_id_t inDriverId, DriverVoteResponse inDriverResponse);
            virtual void getAppropriateDriverId(driver_id_t * inDriverId); //with min response time

        private:

            order_id_t m_order_id;
            time_t m_time_until;
            std::vector<DriverResponse> m_drivers_responses;
            std::vector<driver_id_t> m_permitted_drivers;
        };

class VoteContainer {
public:

    VoteContainer() {};
    virtual ~VoteContainer() {};

    void registerVote(order_id_t inOrderId, std::vector<driver_id_t> inPermittedDrivers, int inSeconds);

private:
    std::map<order_id_t, Vote> m_votes;
};

以及我如何使用它:

//VoteContainer.cpp
void VoteContainer::registerVote(order_id_t inOrderId, std::vector<driver_id_t> inPermittedDrivers, int inSeconds) {
        m_votes.insert(std::make_pair(inOrderId,  Vote(inOrderId, inPermittedDrivers, inSeconds)));
    return;
};

无论我做什么,我都有段错误:

m_votes.insert(std::make_pair(inOrderId,  Vote(inOrderId, inPermittedDrivers, inSeconds)));

我尝试先使用 std::map::find(...) ,但结果相同。回溯:

#0 0x41096a std::less<unsigned int>::operator() (this=0x407a59, __x=@0x7fffffff0b50, __y=@0x758948f87d894905) (/usr/include/c++/4.4/bits/stl_function.h:230)
#1 0x4105fb std::_Rb_tree<unsigned int, std::pair<unsigned int const, Vote>, std::_Select1st<std::pair<unsigned int const, Vote> >, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, Vote> > >::_M_insert_unique(this=0x407a59, __v=...) (/usr/include/c++/4.4/bits/stl_tree.h:1170)
#2 0x40fb25 std::map<unsigned int, Vote, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, Vote> > >::insert(this=0x407a59, __x=...) (/usr/include/c++/4.4/bits/stl_map.h:500)
#3 0x40f06f VoteContainer::registerVote(this=0x407a51, inOrderId=1, inPermittedDrivers=..., inSeconds=32) (/home/user/workspace/src/merit_your_name/VoteContainer.cpp:81)

我想段错误的原因是参数__y=@0x758948f87d894905。我不知道这是为什么!那时 m_votes 地图是空的。请给我建议...

正如 Matthieu M. 所说,最可能的原因是未初始化值 __y=@0x758948f87d894905,但 __y 的类型为 order_id_t 而不是 Vote

我已经尝试重写代码:

std::map<int, int> m_votes;

这并没有解决我的问题,因此,问题不在我的类型中......

这里是调用registerVote()方法的代码。

void OrderProcessor::processOrder(Order inOrder) {
    //test!!!
    driver_id_t driver_ids[] = {1,2};
    std::vector<driver_id_t> drivers(driver_ids, driver_ids + sizeof(driver_ids) / sizeof(driver_id_t) );

    m_vote_container->registerVote(inOrder.getId(), drivers, 32);

    for(size_t i = 0; i < drivers.size(); i++) {
        std::cout << "sending vote to " << drivers[i] << " driver. " << std::endl;
        std::cout << "send returns " << Arch::send_to_socket_nonblock((*m_drivers_connections)[drivers[i]], "<vote>1</vote>") << std::endl;
    }

    sleep(32);

    Vote vote = m_vote_container->getVote(inOrder.getId());
    vote.getAppropriateDriverId(driver_id);
    m_vote_container->deleteVote(inOrder.getId());
};

昨天,我发现我的代码没有问题!我已将 std::map 替换为其他 stl 结构,但结果是一样的!我已经从该代码中删除了 stl 并且 segfault 在 Vote 构造函数中,我已经删除了这个类并且 segfault 在我的代码的其他 stl 结构中!那是什么?请帮帮我。

我找到了问题的原因,不是这段代码。问题出在我之前的代码中。感谢大家参与本次讨论。

【问题讨论】:

    标签: c++ stl stdmap segmentation-fault


    【解决方案1】:

    据我所见,我敢说真正重要的代码丢失了。

    如前所述:this=0x407a59, __x=@0x7fffffff0b50, __y=@0x758948f87d894905 很奇怪,地址之间的距离太远了,所以我们可以假设其中一个(至少)只是未初始化。为了我自己的理智,我假设您对std::map 的实现没有错误。

    我的直觉是寻找未初始化的地图,因此,未初始化的VoteContainer 对象。在调用registerVote 之前,您会忘记分配一些VoteContainer* 吗?

    【讨论】:

    • +1,或者已经销毁的VoteContainer(您是否将指针保存在自动VoteContainers 中?您可能已经删除了VoteContainer 并稍后尝试使用该指针吗?)
    • VoteContainer 无法取消初始化,因为它首先初始化。我没有动态分配VoteContainer,我在程序开始时静态地分配。它首先是程序的多线程部分,但我以单线程方式重写,所以所有对象都必须存在。
    【解决方案2】:

    如果你在 Linux 下工作,我可以推荐 valgrind 工具,它应该可以帮助你找到问题所在

    【讨论】:

    • 我想 valgrind 会将我指向“#0 0x41096a std::less::operator() (this=0x407a59, __x=@0x7fffffff0b50, __y=@0x758948f87d894905)”作为调用堆栈做过。但我会试试的。
    【解决方案3】:

    两种猜测:

    1. 您能显示调用registerVote() 方法的代码吗? (我怀疑这可能会提供一些线索。)

    2. 你能放吗

      m_votes.clear();

    VoteContainer 构造函数中?

    【讨论】:

    • m_votes.clear() 没有解决问题...我认为问题不在我的代码中,我可以尝试做什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-20
    • 2015-09-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多