MaiSakurajima
MaiSakurajima

Reputation: 13

0xC0000005: Access violation reading location 0x005EF9E4

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!

Upvotes: 0

Views: 241

Answers (2)

Alex
Alex

Reputation: 877

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);
}

Upvotes: 1

David Schwartz
David Schwartz

Reputation: 182883

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.

Upvotes: 2

Related Questions