简体   繁体   English

由于互斥锁,C ++向量擦除迭代器超出范围

[英]C++ vector erase iterator out of range due to mutexes

So, there is a vector of strings. 所以,有一个字符串向量。 Since its a static member of cl_mgr class, it acts as global variable. 由于它是cl_mgr类的静态成员,因此它充当全局变量。

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()); 这是它出错的地方:行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. 这应该只在vector为空时发生,但我已经在while条件下检查了这个。

So next i added sizes array to fill it with to_send_queue.size() and found out sometimes it returns zero ! 接下来我添加了sizes数组,用to_send_queue.size()填充它,有时发现它返回零! Usually all array consists of 1's, but sometimes an element like sizes[9500] is a 0. 通常所有数组都包含1个,但有时像size [9500]这样的元素是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();

This std::mutex is local to the method. 这个std::mutex是方法的本地。 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 . 要解决此问题,必须将互斥锁移动到与向量to_send_queue相同的范围,并使用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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM