13

这是一个使用 WinAPI 的 WriteFile(在 Microsoft Visual C++ 2008 Express 中编译)的“Hello world”程序:

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++

消息:“srgprc2.exe 中 0x75ce85ea (KernelBase.dll) 处的未处理异常:0xC0000005:访问冲突写入位置 0x00000000。”

这里发生了什么?谢谢!

4

2 回答 2

19

第四个参数 toWriteFile 不是可选的。您正在传递 NULL,这是不允许的。

于 2011-11-19T17:16:13.753 回答
0

第 4 个参数(告诉我们实际写入了多少字节)期望指向 DWORD 值的指针(又名 unsigned int),当您将 NULL 传递给该参数时,它会尝试将 DWORD 写入导致异常的空指针,不仅是强制传递指向该参数的指针,但您也应该在写入后始终检查它的值,因为尽管 WriteFile 写入的数据量可能比您提供的少,但可能性很小。

于 2017-08-05T02:07:06.010 回答