Q:

C++ "deque iterator not dereferencable" multithreading. WaitForSingleObject() lets the thread through

When im calling WaitForSingleObject() in my Pop() function even if the event notempty is NOT set it doesnt stop it, i dont know what to do with it.
it should wait for a number to be pushed, and even if it is not pushed, it should still wait for an INFINITE amount of time.
same when calling WaitForSingleObject() in Push() when the event notfull is NOT set.

working in Microsoft VS RC 2017 with character set not set.
I dont know how to get this working (waiting for infinite time to push/pop something).
   #include <windows.h>
#include <conio.h>
#include <iostream>
#include <string>
#include <fstream>
#include <time.h>
#include <stack>
using namespace std;
class MonitorStack {
public:
    CRITICAL_SECTION cs_pop;
    CRITICAL_SECTION cs_push;
    stack<int> item;
    int MAXSIZE;
    HANDLE notempty, notfull;
    MonitorStack(int _size) {
        InitializeCriticalSection(&cs_push);
        InitializeCriticalSection(&cs_pop);
        MAXSIZE = _size;
        notempty = CreateEvent(NULL,TRUE,FALSE, "notempty");
        notfull= CreateEvent(NULL, TRUE, TRUE, "notfull");
        SetEvent(notfull);
    }
    MonitorStack() {
        InitializeCriticalSection(&cs_push);
        InitializeCriticalSection(&cs_pop);
        int _size = 0;
        MAXSIZE = _size;
        notempty = CreateEvent(NULL, FALSE, FALSE, "notempty");
        notfull = CreateEvent(NULL, FALSE, TRUE, "notfull");
        SetEvent(notfull);
    }
    ~MonitorStack() {
        MAXSIZE = -1;
    }
    void  Push(int element){
                if (item.size() >= MAXSIZE) {
                    ResetEvent(notfull);
                }
                EnterCriticalSection(&cs_push);
                WaitForSingleObject(notfull, INFINITY);
                    item.push(element);
                    cout << "pushed " << element << endl;
                    SetEvent(notempty);
                    if (item.size() == MAXSIZE) {
                        ResetEvent(notfull);
                    }
                LeaveCriticalSection(&cs_pop);
    }
    int  Pop(){
                if (item.size() == 0) {
                    ResetEvent(notempty);
                }
                EnterCriticalSection(&cs_pop);
                WaitForSingleObject(notempty, INFINITY);
                int num = item.top();
                cout << "popped " << num << endl;
                item.pop();
                SetEvent(notfull);
                if (item.size() == 0) {
                    ResetEvent(notempty);
                }
                LeaveCriticalSection(&cs_push);
                return num;
    }
};
MonitorStack item;
DWORD WINAPI consumerFunction(LPVOID data)
{
    int* info = (int*)data;
    for (int i = 0; i < *info; i++) {
        item.Pop();
    }
    return 0;
}
DWORD WINAPI producerFunction(LPVOID data)
{
    int* info = (int*)data;
    int num;
    srand(time(NULL));
    for (int i = 0; i < *info; i++) {
        num = (rand() % 10 + 1);
        item.Push(num);
    }
    return 0;
}
void main() {
    DWORD  IDThread;
    int cap;
    cout << "enter the capacity of the stack" << endl;
    cin >> cap;
    int producer, consumer;
    cout << "enter the producer and consumer count!" << endl;
    cin >> producer >> consumer;
    HANDLE  *consumerThread = new HANDLE [consumer];
    HANDLE *producerThread = new HANDLE[producer];
    cout << "enter now for each producer the amount of items to produce" << endl;
    int *producercount = new int[producer];
    int *consumercount = new int[consumer];
    item = MonitorStack(cap);
    for (int i = 0; i < producer; i++)
    {
        cin >> producercount[i];
    }
    cout << "enter now for each consumer the amount of items to consume" << endl;
    for (int i = 0; i < consumer; i++)
    {
        cin >> consumercount[i];
    }
    for (int i = 0; i < producer; i++)
    {
        producerThread[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)producerFunction, (void*)&(producercount[i]), 0, &IDThread);
    }
    for (int i = 0; i < consumer; i++)
    {
        consumerThread[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)consumerFunction, (void*)&(consumercount[i]), 0, &IDThread);
    }
    WaitForMultipleObjects(producer, producerThread, TRUE, INFINITE);
    WaitForMultipleObjects(consumer, consumerThread, TRUE, INFINITE);
    for (int i = 0; i < producer; i++)
    {
        CloseHandle(producerThread[i]);
    }
    for (int i = 0; i < consumer; i++)
    {
        CloseHandle(consumerThread[i]);
    }
    system("pause");
}

A:

Your calls to WaitForSingleObject are using INFINITY for the timeout parameter, and instead should be using INFINITE.

