2011-11-19 87 views
11

下面是一個使用WinAPI的的WriteFile的一個 「Hello World」 程序(編譯在Microsoft Visual C++ 2008年速成):爲什麼WriteFile在寫入標準輸出時崩潰?

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

消息: 「訪問衝突寫入位置00000000未處理的異常在0x75ce85ea(KernelBase.dll)在srgprc2.exe:0000005。」

這是怎麼回事嗎?謝謝!

+3

刪除CloseHandle()調用。 –

+0

...應該清楚,因爲您正在使用「Get ...」功能,而不是「Open ...」功能。 –

+0

CloseHandle甚至沒有調用,崩潰發生在WriteFile中,程序終止。 – user38329

回答

17

第四個參數爲WriteFileis not optional。您傳遞NULL,這是不允許的。

+3

D'OH! 「只有當lpOverlapped參數不爲NULL時,此參數纔可以爲NULL。」 http://msdn.microsoft.com/en-us/library/windows/desktop/aa365747%28v=vs.85%29.aspx – Mordachai

+0

謝謝。原型中的「__out_opt」使我困惑不解。 – user38329

+0

我也遇到與問題中提到的OP相同的問題。據我記得,我也通過NULL的參數。所以......感謝您的傑出答案。並且是... +1 :) –

0

第四個參數(它告訴我們多少字節是如何實際寫入)期待指針DWORD值(又名無符號整數),當你傳遞NULL給它試圖寫入DWORD到空指針導致的異常,而不是參數只有傳遞指向該參數的指針纔是必需的,但是在寫入之後也應該始終檢查它的值,因爲儘管有些可能,但WriteFile將寫入的數據少於您提供的數據。

相關問題