QRubberBand:崩溃与BAD ACCESS错误

时间:2013-08-24 13:48:28

标签: qt

我遇到了一些直接脱离Qt帮助的QRubberBand代码崩溃。崩溃发生在setGeometry电话。由于我能够使用qDebug访问几何体,因此创建了QRubberBand实例,所以我很困惑。

上下文:代码在一个自定义的Widget中,它是这样创建的:

   ImageLabel2* image = new ImageLabel2(this);
   image->setPixmap(pix);
   setCentralWidget(image);

我知道该实例仍然存在,因为注释掉setGeometry调用以避免崩溃,继续输出调试语句。

我做错了什么?

调试输出:

  

mousePress QPoint(294,343)
  该计划意外地完成了。


来自崩溃日志:

  

异常类型:EXC_BAD_ACCESS(SIGSEGV)异常代码:   0x000000000000000d,0x0000000000000000


代码:

void ImageLabel2::mousePressEvent(QMouseEvent *event)
{
    qDebug() << "mousePress" << event->pos();

    origin = event->pos();

    if (!rubberBand){
        rubberBand = new QRubberBand(QRubberBand::Rectangle, this); 
    }
    qDebug() <<  rubberBand->geometry();
    rubberBand->setGeometry(QRect(origin, QSize())); // CRASH
    rubberBand->show();
}

2 个答案:

答案 0 :(得分:2)

UPD:根据新信息,问题在于初始化。

通过支票

if (!rubberBand){
    rubberBand = // initialize it
}

您希望rubberBand指针最初等于零(NULL),并检查它。但除非你初始化这个指针,否则它既不会是0也不会是正确的地址。与任何其他未初始化的变量一样,它将包含 garbage ,即瞬间发生在内存中的一些随机值。使用这样的指针可以保证崩溃。

所以,对未初始化的变量说不!如果您希望它最初为NULL,使其为NULL。

因此,在您的自定义窗口小部件构造函数中将其初始化为

ImageLabel2::ImageLabel2() : rubberBand(NULL) {
    // your constructor code
}

ImageLabel2::ImageLabel2() {
    rubberBand = NULL;
    // your constructor code
}

(没有区别)。如果您愿意,可以写0而不是NULL,但NULL更常见。

之后,mousePressEvent方法不需要修改。


旧答案(错误):

来自QSize default constructor的文档:

  

QSize :: QSize()

     

构造一个宽度和高度无效的大小   (即isValid()返回false)。

因此,您创建了一个无效的 QSize并将其传递给QRect。之后的崩溃可能是QRect或QRubberBand代码中的某种错误,或者未定义的行为。如果你想要0到0的大小,那么你应该使用QSize(0,0)。这样的大小有效

  

bool QSize :: isValid()const

     

如果width和height都等于或大于0,则返回true;否则返回false。

答案 1 :(得分:0)

您的错误可能来自您传递QSize()作为参数的事实。

作为文档状态,QSize的默认构造函数创建一个无效对象