глобальные указатели на объекты будут нарушать программу при нарушении прав доступа при доступе к ним через атрибуты / методы объекта - PullRequest
0 голосов
/ 15 апреля 2011

Это код для приложения OpenGL, которое я делаю.У меня есть следующий код, который вызывает нарушение прав доступа (обратите внимание: я только опубликовал код, относящийся к проблеме):

// file: myHeader.h
class MyClass{
    int classAttribute;
  public:
    void myClassFunction();
    bool CreateGLWindow();
    friend LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
    MyClass();
   ~MyClass();
}

//file: myHeader.cpp
bool MyClass::CreateGLWindow(){
    WNDCLASS    wc;
    wc.lpfnWndProc = (WNDPROC) WndProc;
}
void MyClass::myClassFunction(){
    // do stuff
}

MyClass::MyClass(void){
    CreateGLWindow();
}
//file main.cpp
#include myHeader.h

MyClass *p;

LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
  if (p->classAttribute){
     p->myClassFunction();
  }
}

int main(){
    MyClass obj;
    p = &obj;
    BOOL done=FALSE;

    while(!done)                                
    {
      if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))// Is There A Message Waiting?
      {
        if (msg.message==WM_QUIT) // Have We Received A Quit Message?
        {
        done=TRUE;
        }
        else    // If Not, Deal With Window Messages
        {
                TranslateMessage(&msg);
                DispatchMessage(&msg);  
        }
      }
      else // If There Are No Messages
      {
    // Draw The Scene.  Watch For ESC Key And Quit Messages From DrawGLScene()
        if (obj.active)                     // Program Active?
        {
          if (obj.keys[VK_ESCAPE])  
          {
        done=TRUE;
          }
          else  // Not Time To Quit, Update Screen
          {
        DrawGLScene();      
        obj.Swap();         // Swap Buffers (Double Buffering)
          }
        }
        if (obj.keys[VK_F1])
        {
          obj.keys[VK_F1]=FALSE;    
          if (!obj.changeScreenMode())
          {
            return 0; // Quit If Window Was Not Created
          }
        }
      }
    }
}
}

Что я получаю, это нарушение прав доступа в строке p->classAttribute и отладкапоказывает, что атрибуты и методы p не могут быть оценены.

Любая помощь будет принята с благодарностью.

Ответы [ 2 ]

2 голосов
/ 15 апреля 2011

Кажется, конструктор создает окно и связывает WndProc до назначения p (следующая строка кода)

MyClass obj;
    p = &obj;

Вы можете установить MyClass * p = NULL; а затем оберните использование р в

LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
  if(p)
  {
     if (p->classAttribute){
        p->myClassFunction();
  }
}
1 голос
/ 15 апреля 2011

Не уверен, насколько это будет полезно, но я все равно его выброшу.

p указывает на адрес obj.Нарушение доступа, скорее всего, связано с тем, что p обращается к obj вне области (таким образом, obj удаляется из стека), или вы топаете память obj.Это причина, почему obj не может быть оценен отладчиком.Я бы порекомендовал пару вещей, чтобы помочь с проблемой.

0) Зарегистрируйте область памяти, на которую указывает p (используйте %p в printf/_snprintf), и укажите область памяти в ключевых точках в жизненном цикле obj s.
1) getсамостоятельно adplus (часть средств отладки для Windows) и запустите его в режиме сбоя для вашего процесса.
2) Отладьте вывод adplus с помощью вашего любимого отладчика (мой в WinDbg).

Если хужеВ худшем случае включите параметры границ страницы памяти в окнах, которые должны вызвать сбой программы при попытке доступа к защищенным ячейкам памяти.Конечно, предложение GrayDad предотвратит сбой, остановив доступ к нулевому указателю ... если только объект obj не поврежден, в этом случае указатель просто указывает на испорченную память, и он все равно будет падать.Попробуйте сначала его решение.:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...