2014-02-09 110 views
1

所以,存在一个字符串向量。由于它是cl_mgr类的静态成员,因此它充当全局变量。由于互斥体,C++矢量擦除迭代器超出范围

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

但是,我没有直接访问我的代码中的这个向量。为字符串添加到它我叫下面的函数:

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(); 
} 

这是它出错:行 cl_mgr :: to_send_queue.erase(cl_mgr :: to_send_queue.begin()); 有时会使迭代器超出范围。 这应该只发生在向量为空的时候,但我已经在while条件中检查了这个。

所以接下来我添加了sizes数组来填充to_send_queue.size(),并且发现它有时会返回零!通常所有数组都由1组成,但有时像size [9500]这样的元素是0.

什么是错的,以及如何解决这个问题?

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(); 

回答

3

这个std::mutex是本地的方法。这意味着每个这种方法的调用都有自己的互斥体,并且不能保护任何东西。

要解决此问题,您必须将互斥锁移动到与向量to_send_queue相同的范围,并使用std::lock_guard。在网站上,有一个示例如何使用此

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 
} 
+0

这解决了这个问题。谢谢 ! – user1849353