简体   繁体   中英

WriteConsole access violation in function call but not from main()

I am trying to use WriteConsole(..) in a function call but I get access violation. When I un-comment the code in main, it prints my text to the screen with no problem in the main function. When I try to print the string in the function call I get access violation even though it does print the text to the console.

void print(char *_charArray);

int _tmain(int argc, _TCHAR* argv[])
{

    HWND hConsole;
//    HANDLE hFile;
    char myText[] = "This is my text";
    char *pMyText = myText;
    LPDWORD charsWriten;


//    hFile = CreateFile("CONOUT$", GENERIC_WRITE, FILE_SHARE_READ, NULL,
//        OPEN_EXISTING, 0, NULL);

    print(pMyText);

//    WriteConsole(hFile, myText, sizeof(myText), charsWriten, NULL);


    getch();
    return 0;
}

void print(char *text)
{
    LPDWORD charsWriten;
    HANDLE hFile;

    hFile = CreateFile("CONOUT$", GENERIC_READ | GENERIC_WRITE,
                    FILE_SHARE_WRITE | FILE_SHARE_READ, NULL,
                    OPEN_EXISTING, 0, NULL);

    unsigned int strn = strlen(text) + 1;

    if(!WriteConsole(hFile, text, (strlen(text) + 1), charsWriten,NULL))
    {
        printf("Write Failed\n");
    }
}

This declaration is wrong:

LPDWORD charsWriten;

The CreateFile function expects the fourth parameter to be a pointer to a variable it can write into. You don't actually allocate memory, though; you just declare a pointer—an uninitialized one at that. That won't work. You need to do:

DWORD charsWritten;

...

WriteConsole(hFile, text, (strlen(text) + 1), &charsWritten, NULL)

That will fix the access violation problem, but it doesn't explain why you are writing one character past the end of your string. You don't need to add 1 to strlen ; the terminating NUL doesn't need to be written.

LPDWORD charsWriten;

LPDWORD is DWORD* . So what you have there is an uninitialized pointer. You then pass this pointer to WriteConsole , which writes to the invalid location pointed to. Instead, declare charsWritten as type DWORD , and pass its address to WriteConsole with &charsWritten .

DWORD charsWritten;
WriteConsole(hFile, text, (strlen(text) + 1), &charsWritten, NULL);

If, as you say, it works as you have it in main. That is simply bad luck. It's undefined behavior, which doesn't always have predictable results.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM