mardi 21 juillet 2015

Access violation reading location from calling function from pointer

I'm struggling with an Error "Access violation reading location" by calling a function from a pointer, that must push back again an object into a queue.

My idea is to have a class Timer that creates a Time object, and sends it to a TimerServer. After the server triggers the timer, is should remove it from the queue, and then pushing back again to the queue (to have that ordered). I can access the Timer class methods because on my struct Time, I have a Timer* called m_timerptr. And from there, I can access the object...

Any ideas what am I missing here?

Here is my code:

[Timer.hpp]

typedef std::function<void()> callback_type;
typedef std::chrono::time_point<std::chrono::system_clock> time_type;

class Timer;

struct Time
{
    callback_type   m_callback;
    unsigned int    m_ms;
    time_type       m_when;
    Timer*          m_timerptr;
};

class Timer
{
public:
    Timer (const callback_type &cb);

    ~Timer() {};

    void set(const unsigned int ms);

private:

    std::shared_ptr<Time>   m_ptr;
    callback_type           m_callback;

};

[Timer.cpp]

Timer::Timer (const callback_type &cb)
{
    Time t;
    t.m_callback = cb;
    t.m_ms = 0;
    t.m_when = std::chrono::system_clock::now();
    t.m_timerptr = this;

    m_ptr = std::make_shared<Time>(t);
}

void Timer::set(const unsigned int ms)
{
    auto when = std::chrono::system_clock::now() + std::chrono::milliseconds(ms);
    m_ptr->m_when = when; //ERROR is here when called from the TimerServer::loop() function
    m_ptr->m_ms = ms;
    TimerServer& t = TimerServerProvider::getTimerServer();
    t.push (m_ptr);
}

[TimerServer.hpp]

class TimerServer
{
private:

    typedef std::function<void()> callback_type;
    typedef std::chrono::time_point<std::chrono::system_clock> time_type;

    struct time_less
    {
        bool operator()(std::shared_ptr<Time> e1, std::shared_ptr<Time> e2) const
        {
            return (e2->m_when < e1->m_when);
        }
    };

    std::priority_queue<std::shared_ptr<Time>, std::vector<std::shared_ptr<Time>>, time_less> time_queue;

public:
    typedef std::shared_ptr<Time> time_ptr;

    TimerServer() {};

    ~TimerServer() {};

    void push(std::shared_ptr<Time> t);

    void loop(void);
};

[TimerServer.cpp]

void TimerServer::push(std::shared_ptr<Time> t)
{
    time_queue.push(t);
}

void TimerServer::loop(void)
{
    while (true)
    {
        TimerServer::time_type now = std::chrono::system_clock::now();

        while (!time_queue.empty())
        {
            Time* t = time_queue.top().get();

            if (t->m_when < now)
            {
                t->m_callback();
                Timer* tptr = t->m_timerptr;
                tptr->set(t->m_ms); //<--- ERROR!!!!

                time_queue.pop();
            }
            else
                break;
        }
    }
}

Aucun commentaire:

Enregistrer un commentaire