2012-01-08 2 views
0

Я понятия не имею, почему это происходит; некоторые поисковые запросы Google заставили меня поверить, что это связано с неправильным управлением памятью, в то время как другие заявили, что это связано с недопустимым .DLL, связанным с исполняемым файлом. Я не могу понять это, потому что единственный .DLL, который я мог бы назвать недопустимым, - это мой freeglut .DLL, но это нормально работает без проблем.Нарушение права доступа на 0xccccc

Все, что я пытаюсь сделать, это создать окно.

Вопрос

Что происходит с моим кодом? Что я делаю неправильно, и как я могу это исправить?

Код

WinMain

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
LPSTR lpszCmdLine, int nCmdShow) { 

    WNDCLASSEX wc; 
    HWND hwnd; 
    MSG  msg; 
    bool done; 

    wc.cbSize = sizeof(WNDCLASSEX); 
    wc.style = CS_HREDRAW | CS_VREDRAW; 
    wc.lpfnWndProc = WndProc; 
    wc.cbClsExtra = 0; 
    wc.cbWndExtra = 0; 
    wc.hInstance = hInstance; 
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); 
    wc.hCursor = LoadCursor(NULL, IDC_ARROW); 
    wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); 
    wc.lpszClassName = L"someclass"; 

    if (!RegisterClassEx(&wc)) { //Error: 
     MessageBox(NULL, L"Class registration has failed!", L"Error!", MB_OK | MB_ICONINFORMATION); 
     return 0; 
    } 

    hwnd = CreateWindow(
     L"someclass", L"someclass", 
     WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_SYSMENU, 
     200, 200, 400, 400, NULL, NULL, hInstance, NULL 
     ); 

    if (!hwnd) { 
     MessageBox(NULL, L"Window Creation Failed!", L"Error!", MB_OK | MB_ICONINFORMATION); 
    } 

    done = false; 

    while(!done) { 
     PeekMessage(&msg, hwnd, NULL, NULL, PM_REMOVE); 

     if (msg.message == WM_QUIT) { 
      done = true; 
     } else { 
      TranslateMessage(&msg); 
      DispatchMessage(&msg); 
     } 
    } 

    return msg.wParam; 

} 

stdafx.h < - прекомпилирована Заголовок

#ifndef STDAFX_H 
#define STDAFX_H 

#include <Windows.h> 
#include <WinUser.h> 
#include <GL\freeglut.h> 

#endif 

WndProc

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { 
    PAINTSTRUCT paintstruct; 
    HDC hdc; 
    LPCWSTR str = L"Hello, World!"; 

    switch(message) { 
    case WM_PAINT: 
     hdc = BeginPaint(hwnd, &paintstruct); 
     SetTextColor(hdc, COLORREF(0x00FF0000)); 
     TextOut(hdc, 200, 200, str, sizeof(str) - 1); 
     EndPaint(hwnd, &paintstruct); 
     return 0; 
     break; 

    case WM_CLOSE: 
     PostQuitMessage(0); 
     return 0; 

    case WM_CREATE: 
     return 0; 
    } 

    return DefWindowProc(hwnd, message, wParam, lParam); 
} 

Официальный Ошибка

Access violation reading location 0xcccccccc.

Update

Если //Error комментарий отмечен, по RegisterClassEx, в if, где происходит ошибка.

+2

На какой строке кода происходит нарушение доступа? Это первый шаг в определении причины. –

+0

Где происходит ошибка? '0xcc' - это символ заполнения, с которым среда выполнения отладки инициализирует стек. Эта ошибка означает, что вы используете неинициализированную переменную - возможно, указатель. –

+0

Не могли бы вы выслать код для 'WndProc'? – Mehrdad

ответ

4

Вы не инициализируются все данные данных wc (hIconSm и lpszMenuName). Перед тем, как начать использовать его, вы должны инициализировать wc. Например:

WNDCLASSEX wc((WNDCLASSEX())); 

0xcc является символ-заполнитель, с которым отладки во время выполнения инициализации стека перед тем ваша функция вводится. Когда вы видите это значение (и его значение не ожидается), это означает, что вы используете переменную, которую вы не смогли инициализировать.

+0

Блестящий! Спасибо. Быстрый вопрос: почему вы обернули 'WNDCLASSEX()' в parens? Кроме того, зачем передавать это специально, а не просто 'WNDCLASSEX wc();' является конструктором копирования? – zeboidlund

+1

'WNDCLASSEX wc();' является объявлением функции (объявлением функции _vexing_). 'WNDCLASSEX wc (WNDCLASSEX());' также является объявлением функции (объявление _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ __ _ Дополнительные скобки необходимы, чтобы сделать это объявлением переменной. Конечно, вы можете использовать любой метод, который вы хотите инициализировать. –

+2

Гораздо проще: 'WNDCLASSEX wc = {};' Или даже 'WNDCLASSEX wc = {sizeof wc};' –

5

0xCCCCCCCC - это волшебное число, используемое библиотекой времени отладки Microsoft C++ для отметки неинициализированной памяти стека. Вы не указываете, на какой строке вы получаете эту ошибку, что затрудняет точное определение какой переменной не инициализируется.

Другие magic numbers from this series включают:

  • 0xABABABAB Используется Microsoft, HeapAlloc() отметить «Ничья земля» сторожевые байт после того, как выделяется память кучи
  • 0xBAADF00D Используется Microsoft, LocalAlloc(LMEM_FIXED) отметить неиницализированные Обозначенная памяти кучи
  • 0xCDCDCDCD Используется библиотекой времени отладки Microsoft C++ для отметки неинициализированной памяти кучи
  • 0xDDDDDDDD Используется SmartHeap от MicroQuill и кучей отладки Microsoft C++, чтобы отметить освобожденную кучную память
  • 0xDEADDEAD Код ошибки Microsoft Windows STOP, используемый, когда пользователь вручную инициирует сбой.
  • 0xFDFDFDFD Используется C от Microsoft ++ отладочной кучи, чтобы отметить «ничейная земля» сторожевые байт до и после выделенной памяти кучи
  • 0xFEEEFEEE Используется Microsoft, HeapFree() отметить освобожденный память кучи
+2

Может быть, неплохо включить ссылку на источник. –

+0

@BenVoigt: Ты прав. Готово. – Johnsyweb

Смежные вопросы