Home > database >  0xC0000005: Access violation reading location 0x005EF9E4
0xC0000005: Access violation reading location 0x005EF9E4

Time:02-22

I am having issues with Handles. I have Bytebeat (music in bytes) playing inside of a DWORD WINAPI function. When I try to terminate and close the thread, it straight up gives me the error in the title. This is my code:

#include <windows.h>
#pragma comment(lib, "Winmm.lib")

DWORD WINAPI bytebeat1(LPVOID) {
    while (1) {
        HWAVEOUT hwo = 0;
        WAVEFORMATEX wfx = { WAVE_FORMAT_PCM, 1, 11000, 11000, 1, 8, 0 };
        waveOutOpen(&hwo, WAVE_MAPPER, &wfx, 0, 0, CALLBACK_NULL);

        char buffer[11000 * 6];

        for (DWORD t = 0; t < sizeof(buffer); t  )
            buffer[t] = static_cast<char>(t & t   t / 256) - t * (t >> 15) & 64;

        WAVEHDR hdr = { buffer, sizeof(buffer), 0, 0, 0, 0, 0, 0 };
        waveOutPrepareHeader(hwo, &hdr, sizeof(WAVEHDR));
        waveOutWrite(hwo, &hdr, sizeof(WAVEHDR));
        waveOutUnprepareHeader(hwo, &hdr, sizeof(WAVEHDR));
        waveOutClose(hwo);
        Sleep(6000);
    }
}

DWORD WINAPI bytebeat2(LPVOID) {
    while (1) {
        HWAVEOUT hwo = 0;
        WAVEFORMATEX wfx = { WAVE_FORMAT_PCM, 1, 8000, 8000, 1, 8, 0 };
        waveOutOpen(&hwo, WAVE_MAPPER, &wfx, 0, 0, CALLBACK_NULL);

        char buffer[8000 * 6];

        for (DWORD t = 0; t < sizeof(buffer); t  )
            buffer[t] = static_cast<char>(t, t / 5) >> t / 25 & t / 55 ^ t & 255 ^ (t / 150) ^ 2508025 * 24240835810 & (t / 100) * t / 6000 ^ 5000 * t / 2500 ^ 25 * t / 24;

        WAVEHDR hdr = { buffer, sizeof(buffer), 0, 0, 0, 0, 0, 0 };
        waveOutPrepareHeader(hwo, &hdr, sizeof(WAVEHDR));
        waveOutWrite(hwo, &hdr, sizeof(WAVEHDR));
        waveOutUnprepareHeader(hwo, &hdr, sizeof(WAVEHDR));
        waveOutClose(hwo);
        Sleep(6000);
    }
}

int main() {
    HANDLE beat1 = CreateThread(0, 0, bytebeat1, 0, 0, 0);
    Sleep(6000);
    TerminateThread(beat1, 0); CloseHandle(beat1);
    Sleep(1000);
    HANDLE beat2 = CreateThread(0, 0, bytebeat2, 0, 0, 0);
    Sleep(6000);
    TerminateThread(beat2, 0); CloseHandle(beat2);
}

I do not know why this is happening. The only fix is compiling it with G but I want it so I could just build it. Any help is appreciated. Thanks!

CodePudding user response:

When you call TerminateThread, you are basically force-crashing your threads. They still have their own stack allocated and handles to Windows resources. They aren't cleaned up properly, causing your crash.

Here's a simple example of how to close your threads without any error. In a real-world scenario this is an unprofessional solution, but it shows the bare minimum that you need to do.

#include <windows.h>
#pragma comment(lib, "Winmm.lib")

volatile bool quit1 = false;
volatile bool quit2 = false;

DWORD WINAPI bytebeat1(LPVOID) {
    while (!quit1) {
        HWAVEOUT hwo = 0;
        WAVEFORMATEX wfx = { WAVE_FORMAT_PCM, 1, 11000, 11000, 1, 8, 0 };
        waveOutOpen(&hwo, WAVE_MAPPER, &wfx, 0, 0, CALLBACK_NULL);

        char buffer[11000 * 6];

        for (DWORD t = 0; t < sizeof(buffer); t  )
            buffer[t] = static_cast<char>(t & t   t / 256) - t * (t >> 15) & 64;

        WAVEHDR hdr = { buffer, sizeof(buffer), 0, 0, 0, 0, 0, 0 };
        waveOutPrepareHeader(hwo, &hdr, sizeof(WAVEHDR));
        waveOutWrite(hwo, &hdr, sizeof(WAVEHDR));
        waveOutUnprepareHeader(hwo, &hdr, sizeof(WAVEHDR));
        waveOutClose(hwo);
        Sleep(6000);
    }

    return 0;
}

DWORD WINAPI bytebeat2(LPVOID) {
    while (!quit2) {
        HWAVEOUT hwo = 0;
        WAVEFORMATEX wfx = { WAVE_FORMAT_PCM, 1, 8000, 8000, 1, 8, 0 };
        waveOutOpen(&hwo, WAVE_MAPPER, &wfx, 0, 0, CALLBACK_NULL);

        char buffer[8000 * 6];

        for (DWORD t = 0; t < sizeof(buffer); t  )
            buffer[t] = static_cast<char>(t, t / 5) >> t / 25 & t / 55 ^ t & 255 ^ (t / 150) ^ 2508025 * 24240835810 & (t / 100) * t / 6000 ^ 5000 * t / 2500 ^ 25 * t / 24;

        WAVEHDR hdr = { buffer, sizeof(buffer), 0, 0, 0, 0, 0, 0 };
        waveOutPrepareHeader(hwo, &hdr, sizeof(WAVEHDR));
        waveOutWrite(hwo, &hdr, sizeof(WAVEHDR));
        waveOutUnprepareHeader(hwo, &hdr, sizeof(WAVEHDR));
        waveOutClose(hwo);
        Sleep(6000);
    }

    return 0;
}

int main() {
    HANDLE beat1 = CreateThread(0, 0, bytebeat1, 0, 0, 0);
    Sleep(6000);
    quit1 = true;
    WaitForSingleObject(beat1, INFINITE);
    CloseHandle(beat1);
    Sleep(1000);
    HANDLE beat2 = CreateThread(0, 0, bytebeat2, 0, 0, 0);
    Sleep(6000);
    quit2 = true;
    WaitForSingleObject(beat2, INFINITE);
    CloseHandle(beat2);
}

CodePudding user response:

As the documentation makes clear, you can't use TerminateThread this way. Instead, replace the calls to Sleep with an interruptible sleep function that will terminate the thread cleanly and safely if requested to do so.

  •  Tags:  
  • c
  • Related