繁体   English   中英

使用指向creat对象的指针访问冲突错误

[英]Access violation error by using pointer to creat object

所以我刚开始使用C ++进行Windows编程。 首先,我绘制一些线条并且没关系,然后我尝试创建一个用于绘制某些形状的类,当我使用普通方法创建对象时(在代码中这些部分被注释掉),它工作正常,但是当我正在使用指针来创建新对象,我收到了Access violation错误。

这是我的课程(我删除了一些代码,因此在某些部分看起来似乎过于简化了):

class shapes {
public:
   shapes(void);
   void setstartp( POINT& p0);
   void setendp( POINT& p1);

   void draw(HDC hdc);
   ~shapes(void);

   POINT x0;
   POINT x1;
};

shapes::shapes(){}

void shapes::setstartp( POINT& p0){
    x0=p0;
}

void shapes::setendp( POINT& p1){
    x1=p1;
}

void shapes::draw(HDC hdc){
    MoveToEx(hdc,x0.x ,x0.y ,0);
    LineTo(hdc ,x1.x ,x1.y);
}

shapes::~shapes(void) {}

这是我的程序,或者至少是winproc部分:

//shapes sh; 
shapes* sh =0;
bool mousdown =false;

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    POINT p0;
    POINT p1;
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;

    switch (message)
    {
        case WM_LBUTTONDOWN :
            SetCapture(hWnd);
            mousdown = true;

            p0.x = LOWORD(lParam);
            p0.y = HIWORD(lParam);

            // sh.setstartp(p0);
            sh = new shapes();
            sh->setstartp(p0);
            break;    
     case WM_MOUSEMOVE :
         if(mousdown) {
             p1.x = LOWORD(lParam);
             p1.y = HIWORD(lParam);
             // sh.setendp(p1);
            sh->setendp(p1);
            InvalidateRect(hWnd ,0,true);
         }
         break;    
     case WM_LBUTTONUP :
         ReleaseCapture();
         mousdown = false;
         p1.x = LOWORD(lParam);
         p1.y = HIWORD(lParam);

         // sh.setendp(p1);
         sh->setendp(p1);
         InvalidateRect(hWnd ,0,true);
         break;
     case WM_PAINT:
         hdc = BeginPaint(hWnd, &ps);
         // TODO: Add any drawing code here...
         //sh.draw(hdc);
         sh->draw(hdc);
         EndPaint(hWnd, &ps);
         break;
     case WM_COMMAND: 

这是我的Access violation错误:

NEWWIN.exe中0x00411fda处的未处理异常:0xC0000005:访问冲突读取位置0x00000004。

并且错误指向类实现:

 void shapes::draw(HDC hdc) {           
     MoveToEx(hdc,x0.x ,x0.y ,0);
     LineTo(hdc ,x1.x ,x1.y);
 }

显然我的类属性x0x1有问题:

这个0x00000000 {x0 = {...} x1 = {...}}形状* const

x0 {x = ??? y = ???} tagPOINT

x CXX0030:错误:无法计算表达式

y CXX0030:错误:无法计算表达式

x1 {x = ??? y = ???} tagPOINT

x CXX0030:错误:无法计算表达式

y CXX0030:错误:无法计算表达式

问题是在接收(和处理WM_LBUTTONDOWN )事件之前,您不构造shapes对象。 因此,如果之前处理了任何其他事件(例如WM_MOUSEMOVE ),则sh仍将为0。

此外,请注意您在此处有内存泄漏:您调用sh = new shapes(); 对于每个WM_LBUTTONDOWN事件,不会删除以前分配的对象。

我建议你在WM_CREATE处理程序中分配你的shape对象,并在WM_DESTROY处理程序中delete它。

 sh->setendp(p1);

是的,那将是kaboom。 在获得WM_LBUTTONDOWN消息之前,您将始终收到WM_MOUSEMOVE消息。 你还没有创建sh对象。 更改

shapes* sh =0;

shapes sh;

对于一阶修复。

试想一下,如果您的程序按此顺序接收事件会发生什么:

  1. WM_PAINT
  2. WM_MOUSEMOVE
  3. WM_BUTTONDOWN
  4. WM_PAINT
  5. WM_MOUSEMOVE
  6. WM_BUTTONUP
  7. WM_PAINT

在事件3到达之前不会创建shapes对象,但您已尝试在第一个事件中绘制形状。

摆脱崩溃的最简单方法是检查sh不是空指针( if (sh != 0) /* use sh */ ),或者恢复使用非指针。

但是代码中存在更大的问题:

  • 目前你有一个内存泄漏,因为你为每个WM_BUTTONDOWN事件创建一个新的shapes对象,但你永远不会删除它们中的任何一个
  • 如果在设置形状的两个角之前得到WM_PAINT事件,您想要绘制什么? 目前,您将线条绘制到未指定的位置。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM