0
votes

This is code for an OpenGL application i'm making. I have the following code that produces an access violation (notice: i've only posted the code relevant to the problem):

// 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
          }
        }
      }
    }
}
}

What i get is an access violation on the line p->classAttribute and debugging shows that the attributes and methods of p can't be evaluated.

Any help will be greatly appreciated.

2
You need to add some more code from "//code that will eventually call WndProc". p might not be valid by the time the call happens (in fact it is not valid... access violation), so we need to see what you are doing before that call.Dennis
@Dennis updated at your requestValentin Brasso
There's a missing ; after your class, but I take that's a copy/paste/typing error. :)Xeo

2 Answers

2
votes

The constructor seems to create the window and associate the WndProc before p is assigned (the next line of code)

MyClass obj;
    p = &obj;

You could set MyClass * p = NULL; and then wrap the use of p in

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

Not sure how useful this will be, but I'll throw it out there anyways.

p is pointing to the address of obj. The access violation is most likely due to the fact that p is accessing obj outside of scope (thus obj is getting cleared from the stack), or you are stomping on obj's memory. This is the reason why obj cannot be assessed by the debugger. I would recommend a couple of things to help with the problem.

0) Log the memory location that p is pointing to (use %p in printf/_snprintf), and log memory location at key points in objs lifecycle.
1) get yourself adplus (part of Debugging Tools for Windows) and run it in crash mode against your process.
2) Debug the output of adplus with your favourite debugger (mine in WinDbg).

If worst comes to worst turn on the memory page boundary options in windows which should crash the program at attempt to access protected memory locations. Of course grayDad's suggestion will prevent the crash by stopping the access of a NULL pointer... unless obj is corrupted, in which case the pointer is just pointed to messed up memory and it will still crash. Try his solution first. :)