Почему происходит сбой WriteFile при записи в стандартный вывод? - PullRequest
11 голосов
/ 19 ноября 2011

Вот программа «Hello world», использующая WinAPI WriteFile (скомпилированный в Microsoft Visual C ++ 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 существует и содержит правильный вывод полностью.

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

KernelBase.dll!_WriteFile@20()  + 0x75 bytes    
kernel32.dll!_WriteFileImplementation@20()  + 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 ]

17 голосов
/ 19 ноября 2011

Четвертый параметр для WriteFile не является обязательным . Вы передаете NULL, что запрещено.

0 голосов
/ 05 августа 2017

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

...