Home > front end >  How to fix Debug Error from Microsoft Visual C Runtime library when dealing with threads?
How to fix Debug Error from Microsoft Visual C Runtime library when dealing with threads?

Time:11-06

Im writing a program that will detect a key press and do something (in this case show a message box), it all work fine when i try to exit the program it show a popup like this error window. Now this window doesnt mess up anything in my program so i could leave it there but it is annoying. Heres a Minimal Reproducible Sample, im just beginning to code in win32 so please don't criticize my inefficent code

#include <Windows.h>
#include <thread>
#include <chrono>
#define HFFFA               1001
#define MAINWINDOWSTYLE         WS_OVERLAPPED| WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX
std::chrono::milliseconds THREAD_WAIT(50);

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
    switch (msg)
    {
    case WM_COMMAND:
    {

        switch (wp)
        {
        case HFFFA:
        {

            MessageBox(hwnd, L"Sucess", L"Success", MB_OK);
            break;
        }
        break;
        }

        break;

    }
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hwnd, &ps);
        FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW));
        EndPaint(hwnd, &ps);
        break;
    }
    case WM_DESTROY:
    {
        PostQuitMessage(0);
        break;
    }
     break;
    }
    return DefWindowProc(hwnd, msg, wp, lp);
}


void GetKeyPress(HWND hwnd)
{
    int keypressed = -1;
    while (TRUE)
    {
        if (GetAsyncKeyState(VK_F6))
        {
            SendMessage(hwnd, WM_COMMAND, (WPARAM)HFFFA, TRUE);
        }
        std::this_thread::sleep_for(THREAD_WAIT);
    }
}


int WINAPI wWinMain(HINSTANCE hinst, HINSTANCE hiprevinst, PWSTR nCmdLine, int ncmdshow)
{
    const wchar_t CLASS_NAME[] = L"Axom";
    WNDCLASS wc = { };
    wc.lpfnWndProc = WndProc;
    wc.hInstance = hinst;
    wc.lpszClassName = CLASS_NAME;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    RegisterClass(&wc);
    HWND hwnd = CreateWindowEx(0, CLASS_NAME, L"Axom", MAINWINDOWSTYLE, CW_USEDEFAULT, CW_USEDEFAULT, 592, 600, NULL, NULL, hinst, NULL);
    ShowWindow(hwnd, ncmdshow);
    std::thread td(GetKeyPress, hwnd);
    MSG msg;
    while (GetMessage(&msg, NULL, NULL, NULL))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return 0;
}

CodePudding user response:

When the events loop ends all wWinMain local variables are destroyed. One of them is td as your thread. When std::thread is destroyed while it is in joinable state, std::terminate is called:

std::terminate is called by the C runtime when the program cannot continue for any of the following reasons:

  1. a joinable std::thread is destroyed or assigned to

The default std::terminate behaviour is to invoke std::abort function.

The default std::terminate_handler calls std::abort.

You have to detach or join td thread before it is destroyed. If you join the thread, you have to add some mechanism (for example via global flag variable) to inform GetKeyPress thread function when to leave.

std::atomic_bool stopFlag; // global variable

void GetKeyPress(HWND hwnd) {
    int keypressed = -1;
    while (!stopFlag) {
        if (GetAsyncKeyState(VK_F6))
           SendMessage(hwnd, WM_COMMAND, (WPARAM)HFFFA, TRUE);
        std::this_thread::sleep_for(THREAD_WAIT);
    }
}

std::thread td(GetKeyPress, hwnd);
MSG msg;
while (GetMessage(&msg, NULL, NULL, NULL))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}
stopFlag = true;
td.join();
  • Related