所以,有一个字符串向量。由于它是cl_mgr类的静态成员,因此它充当全局变量。
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()); 有时会使迭代器超出范围。 这应该只在vector为空时发生,但我已经在条件状态下检查了这一点。
接下来我添加了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();
答案 0 :(得分: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
}