在使用Layout进行widget移除的过程中,我发现这样的现象:

我将widget用QLayout::removeWidget移除后,栈内存回收,在析构函数中检测widget是否为null,然后释放内存。

gLayout->removeWidget( m_photoFrames[i]->Getm_frame() );
//...
PhotoFrame::~PhotoFrame()
{
    if( nullptr != m_frame )
    {
        delete m_frame;
        m_frame = nullptr;
    }
}

结果程序报错:

Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY

Application Specific Information:
abort() called
imagesViewer(2550,0x116eff5c0) malloc: *** error for object 0x7f9b9cf4f1a0: pointer being freed was not allocated


Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libsystem_kernel.dylib 0x00007fff60c51b86 __pthread_kill + 10
1 libsystem_pthread.dylib 0x00007fff60d07c50 pthread_kill + 285
2 libsystem_c.dylib 0x00007fff60bbb1c9 abort + 127
3 libsystem_malloc.dylib 0x00007fff60cc96e2 malloc_vreport + 545
4 libsystem_malloc.dylib 0x00007fff60cc94a3 malloc_report + 152
5 org.qt-project.QtWidgets 0x000000010b44d80d QWidget::~QWidget() + 413

这是怎么回事儿?
查一查函数的源码:

void QLayout::removeWidget(QWidget *widget)
{
    int i = 0;
    QLayoutItem *child; while ((child = itemAt(i))) {
        if (child->widget() == widget) { delete takeAt(i);
            invalidate();
        } else {
            ++i;
        }
    }
}

原来,removeWidget就有对widget delete的操作,但是QT并没有将其设置为nullptr!
由此形成了内存多次释放的情形。

分类: C plus plus

发表评论

电子邮件地址不会被公开。 必填项已用*标注