2014-02-09 1 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()); 은 종종 iterator가 범위를 벗어난다. 이것은 벡터가 비어있을 때만 발생해야하지만, 이미 조건 동안 이것을 확인합니다.

다음으로 to_send_queue.size()로 채우기 위해 sizes 배열을 추가하고 때로는 0을 반환한다는 것을 알았습니다! 일반적으로 모든 배열은 1로 구성되지만 크기 [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