Почему сбой записи WriteFile при записи на стандартный вывод?

Здесь программа Hello World, использующая WinAPI WriteFile (скомпилированная в Microsoft Visual С++ 2008 Express):

int _tmain(int argc, _TCHAR* argv[])
{
    wchar_t str[] = L"Hello world";

    HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
    if(out && out!=INVALID_HANDLE_VALUE)
    {
        WriteFile(out, str, sizeof(str), NULL, NULL);
        CloseHandle(out);
    }   

    return 0;
}

Если он выполнен в окне консоли, он радостно приветствует мир. Однако, если вы попытаетесь перенаправить свой стандартный вывод, как в

hello.exe > output.txt

программа сбой в WriteFile (исключение указателя NULL). Тем не менее, output.txt существует и содержит корректный вывод целиком.

Стол вызовов при сбое:

[email protected]()  + 0x75 bytes    
[email protected]()  + 0x4e bytes    
srgprc2.exe!wmain(int argc=1, wchar_t * * argv=0x00483d88)  Line 15 + 0x16 bytes    C++

Сообщение: "Необработанное исключение в 0x75ce85ea (KernelBase.dll) в файле srgprc2.exe: 0xC0000005: место записи нарушения доступа 0x00000000."

Что здесь происходит? Спасибо!

Ответ 2

4-й параметр (который говорит нам, сколько байтов фактически записано) ожидает указатель на значение DWORD (aka unsigned int), когда вы передаете NULL этому параметру, он пытается записать DWORD в нулевой указатель, который вызывает исключение, а не только обязательно передавать указатель на этот аргумент, но также вы всегда должны проверять его значение после записи, потому что есть вероятность, хотя и тонкая, что WriteFile будет записывать меньше данных, чем вы предоставили.