Ошибка деструктора shared_ptr<std:: deque>, переданного в качестве аргумента в новый поток

Я передаю структуру params, которая содержит shared_ptr в std::deque, в качестве входного аргумента для функции, которая будет работать в новом потоке. Эта дека создана на внешнем объекте как публичное поле. И когда я сохраняю shared_ptr в params структура, число ссылок в shared_ptr увеличивается, и все, кажется, в порядке.

Что касается потока, он создается с помощью вызова _beginthread() функция. Внутри потока я помещаю некоторые значения в deque, на которые указывает shared_ptr. Эти значения корректно отображаются на внешнем объекте, поэтому, похоже, все снова в порядке.

Когда поток завершает свою работу, структура параметров удаляется из кучи, а счетчик ссылок уменьшается (все снова в порядке). Но когда вызывается деструктор внешнего объекта, где был создан этот shared_ptr, то счетчик refs уменьшается и становится равным 0, поэтому деструктор указанного объекта фактически вызывается, и возникает ошибка отладки диссертации. Неудачное выражение: _pFirstBlock == pHead (двойное удаление?). Но я проверил с помощью точки останова данных на VS2012, что адрес shared_ptr._Rep._Uses Доступ только в моменты, которые я описал выше.

Еще одно замечание: если в эту деку ничего не вставлено, то все деструкторы работают успешно. Что я делаю не так?

typedef std::deque<MsgBuf_ptr> MsgQueue;
typedef std::tr1::shared_ptr<MsgQueue> MsgQueue_ptr;
typedef const MsgQueue_ptr& MsgQueue_ptr_p;

shared_ptr создание:

...
MsgQueue_ptr qMsgQueue;
...
qMsgQueue.reset(new MsgQueue)
...
bool bStartOK = start(qMsgQueue, ghMutex);  

структура параметров потока:

struct ThreadServerParam {  
    HANDLE ghStopEvent;
    MsgQueue_ptr qMsgQueue; 
    HANDLE ghMutex;
};

создание потока:

void start(MsgQueue_ptr_p qMsgQueue, HANDLE ghMutex) {
    param = new ThreadServerParam;
    param->qMsgQueue = qMsgQueue;   
    param->ghStopEvent = ghStopEvent;
    param->ghMutex = ghMutex;

    hThread = (HANDLE)_beginthread( &ThreadFunction, THREAD_STACK_SIZE, param );
    if(hThread == INVALID_HANDLE_VALUE || hThread == NULL) {...}
}

функция потока:

void ThreadFunction(void* ptr) {
    ThreadServerParam *param = (ThreadServerParam*) ptr;    
    while(dwWaitResult != WAIT_OBJECT_0) {          
        findNewMessage(internalQueue);
        if(!msgQueue->empty()) {                
        DWORD dwWaitResult = WaitForSingleObject(param->ghMutex, INFINITE);
        switch (dwWaitResult) {
                case WAIT_OBJECT_0: 
                    while (!msgQueue->empty()) {
                        MsgBuf_ptr msg_buf = internalQueue->front();
                        param->qMsgQueue->push_back(msg_buf);                                   
                        internalQueue->pop_front();
                    }
             ...
            }
          }
          Sleep(GAP);
      dwWaitResult = WaitForSingleObject(param->ghStopEvent, 0);
     }
     delete param;
 }

0 ответов

Другие вопросы по тегам