2011-04-15 81 views
0

这是我制作的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的方法不能被评估。

任何帮助将不胜感激。

+0

您需要从“//最终将调用WndProc的代码”添加更多代码。调用发生的时候'p'可能无效(实际上它不是有效的...访问冲突),所以我们需要在调用之前看看你在做什么。 – Dennis 2011-04-15 09:38:44

+0

@丹尼斯根据您的要求更新了 – 2011-04-15 09:55:37

+0

您的课后缺少';',但我认为这是复制/粘贴/输入错误。 :) – Xeo 2011-04-15 09:59:04

回答

2

的构造似乎创建窗口和关联的WndProc p被分配(的下一行代码)

MyClass obj; 
    p = &obj; 

您可以设置MyClass的* p = NULL之前;然后用p包起来使用

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

辉煌。非常感谢。 – 2011-04-15 10:24:17

1

不知道这个会有多大用处,但是我反正会把它扔掉。

p指向obj的地址。访问冲突很可能是由于p正在访问范围之外的obj(因此obj被从堆栈中清除),或者您正在跺跺obj的内存。这就是调试器无法评估obj的原因。 我会推荐几件事来帮助解决这个问题。

0)登录该p指向(使用printf/_snprintf%p)的存储位置,并在obj小号生命周期的关键点记录存储器位置。
1)弄到你自己adplus(Windows调试工具的一部分),并以崩溃模式对你的进程运行它。
2)用你最喜欢的调试器(我的WinDbg)调试adplus的输出。

如果最坏的情况发生,最坏的情况是打开窗口中的内存页边界选项,这会在试图访问受保护的内存位置时导致程序崩溃。当然,grayDad的建议将通过停止对NULL指针的访问来防止崩溃......除非obj被破坏,在这种情况下,指针只会指向混乱的内存,并且仍会崩溃。先试试他的解决方案。 :)