Question

So, there is a vector of strings. Since its a static member of cl_mgr class, it acts as global variable.

std::vector<std::string> cl_mgr::to_send_queue;

However, i dont ever directly access this vector in my code. To add strings to it i call following function:

void cl_mgr::sendmsg(std::string msg)
{
    std::mutex mtx;

    mtx.lock();
    if ( connected )
    {
        cl_mgr::to_send_queue.push_back(msg + '\r');
    }
    mtx.unlock();
}

This is where it goes wrong: the line cl_mgr::to_send_queue.erase(cl_mgr::to_send_queue.begin()); sometimes gives iterator out of range. This should only happen when vector is empty, but i already check for this in while condition.

So next i added sizes array to fill it with to_send_queue.size() and found out sometimes it returns zero ! Usually all array consists of 1's, but sometimes an element like sizes[9500] is a 0.

Whats wrong and how to fix this ?

std::mutex mtx;
mtx.lock();
while ( !cl_mgr::to_send_queue.empty() )
{
    string tosend = cl_mgr::to_send_queue[0];

    int sizes[10000];
    sizes[0]=0;
    for (int i = 1; i < 10000; ++i)
    {
        sizes[i] = cl_mgr::to_send_queue.size();
        if ( sizes[i] < sizes[i-1] )
        {
            int breakpoint = 0; //should never be hit but it does !
        }
    }

    cl_mgr::to_send_queue.erase(cl_mgr::to_send_queue.begin()); //CRASH HERE

    send(hSocket, tosend.c_str(), tosend.length(), 0 );


    Sleep(5);
}
mtx.unlock();
Was it helpful?

Solution

This std::mutex is local to the method. This means every invocation of this method has it's own mutex and doesn't protect anything.

To fix this, you must move the mutex to the same scope as the vector to_send_queue and use a std::lock_guard. At the website, there is an example how to use this

int g_i = 0;
std::mutex g_i_mutex;  // protects g_i

void safe_increment()
{
    std::lock_guard<std::mutex> lock(g_i_mutex);
    ++g_i;

    std::cout << std::this_thread::get_id() << ": " << g_i << '\n';

    // g_i_mutex is automatically released when lock
    // goes out of scope
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top