[C][筆記] Win8 下 clrscr 函數 0xC0000005 存取違規
今天寫作業遇到的一個問題,害我只能用學校的 XP 寫 (怨念
clrscr 是 conio 裡的一個函數,不過大部分的 header 裡好像都沒有他 (DevC 表示
所以有附上另外的 function 給我們調用,但想不到在 Win8 下居然無法開啟範例程式,就算自己編譯也會錯誤...
本人 Win8 x64,這個程式碼在網路上隨處可見,XP、Win7 測試都沒有問題,回來給他 debug 看問題到底在哪(懶得重寫函數)畢竟聽說之後還會常常用到 (笑
先附上網路上隨處可見的版本
VC 表示:0x76ACED95 (KernelBase.dll) (於 ConsoleApplication2.exe) 中第一個可能發生的例外狀況: 0xC0000005: 寫入位置 0x00000000 時發生存取違規。
去記憶體中看了一下 0x76ACED95 在搞甚麼鬼,KERNELBASE 表示這是 WriteConsoleOutputAttribute 這個 API,然後我們看一下上面那個函數,就知道問題出在 FillConsoleOutputCharacter 這了! (至於怎麼看... 對 API 有一定了解應該看的出來
看一下 MSDN 的介紹...
(有興趣去比較 Kernel 差異的歡迎留言...
講這麼久那到底要怎麼改才能用呢?
只要把原本回傳 LPDWORD lpNumberOfCharsWritten 不要傳到空指標改宣告一個 DWORD 當暫存即可...
clrscr 是 conio 裡的一個函數,不過大部分的 header 裡好像都沒有他 (DevC 表示
所以有附上另外的 function 給我們調用,但想不到在 Win8 下居然無法開啟範例程式,就算自己編譯也會錯誤...
本人 Win8 x64,這個程式碼在網路上隨處可見,XP、Win7 測試都沒有問題,回來給他 debug 看問題到底在哪(懶得重寫函數)畢竟聽說之後還會常常用到 (笑
先附上網路上隨處可見的版本
void clrscr(void) { CONSOLE_SCREEN_BUFFER_INFO sbinf; int size; COORD scrn = {0, 0}; HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); GetConsoleScreenBufferInfo(hStdOut, &sbinf); size = (sbinf.srWindow.Right-sbinf.srWindow.Left+1)* (sbinf.srWindow.Bottom-sbinf.srWindow.Top+1); FillConsoleOutputCharacter(hStdOut, 32, size, scrn, NULL); }Dev 表示:_____(已當
VC 表示:0x76ACED95 (KernelBase.dll) (於 ConsoleApplication2.exe) 中第一個可能發生的例外狀況: 0xC0000005: 寫入位置 0x00000000 時發生存取違規。
去記憶體中看了一下 0x76ACED95 在搞甚麼鬼,KERNELBASE 表示這是 WriteConsoleOutputAttribute 這個 API,然後我們看一下上面那個函數,就知道問題出在 FillConsoleOutputCharacter 這了! (至於怎麼看... 對 API 有一定了解應該看的出來
看一下 MSDN 的介紹...
BOOL WINAPI FillConsoleOutputCharacter( _In_ HANDLE hConsoleOutput, _In_ TCHAR cCharacter, _In_ DWORD nLength, _In_ COORD dwWriteCoord, _Out_ LPDWORD lpNumberOfCharsWritten );根據錯誤訊息,寫入了 0x00000000 這個位置,也就是寫入了一個空指標造成記憶體存取違規程式當掉,雖然不知道為什麼到 Win8 這邊就不能用 NULL 了,只能猜是 Kernel 有改某些使用上變嚴格了吧?
(有興趣去比較 Kernel 差異的歡迎留言...
講這麼久那到底要怎麼改才能用呢?
只要把原本回傳 LPDWORD lpNumberOfCharsWritten 不要傳到空指標改宣告一個 DWORD 當暫存即可...
void clrscr(void) { CONSOLE_SCREEN_BUFFER_INFO sbinf; int size; COORD scrn = {0, 0}; HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); DWORD temp; GetConsoleScreenBufferInfo(hStdOut, &sbinf); size = (sbinf.srWindow.Right-sbinf.srWindow.Left+1)* (sbinf.srWindow.Bottom-sbinf.srWindow.Top+1); FillConsoleOutputCharacter(hStdOut, 32, size, scrn, &temp); }至少我以後可以繼續用我的 Win8 來寫了哼哼啊阿 :P
嘖嘖阿
回覆刪除DROID => DWORD
回覆刪除筆誤已修正。
刪除