QLayout и Valgrind - PullRequest
       42

QLayout и Valgrind

0 голосов
/ 29 апреля 2020

Я боролся с сообщением от Вальгринда. Я использую QLayout, взятый из примеров Qt (FlowLayout), и добавляю во время выполнения, когда пользователь нажимает кнопку добавления, некоторые виджеты для этого макета. Это фрагмент инициализации внутри конструктора моего унаследованного класса QWidget контейнера:

// scroll area
auto* central = new QWidget();
central->setObjectName("CentralWidget");
m_layout = new FlowLayout;
ui->scrollArea_step->setFrameShape(QFrame::NoFrame);
central->setLayout(m_layout);
ui->scrollArea_step->setWidgetResizable(true);
ui->scrollArea_step->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
ui->scrollArea_step->setWidget(central);

Я понял, что из-за setWidget (central) мне не нужно присваивать родительский элемент для "central "widget.

Когда пользователь нажимает кнопку добавления в интерфейсе, программа вызывает следующий фрагмент:

// create the button from rf data
ShortMenuPushButton* stepButton = _createStepButton(m_rfData);
m_layout->addWidget(stepButton);
QPushButton* deleteStepButton = _createDeleteButton();
m_layout->addWidget(deleteStepButton);

_createStepButton имеет следующий код:

auto* stepButton = new ShortMenuPushButton(this);

та же операция выполняется _createDeleteButton () для другой кнопки.

Если я запускаю Valgrind, я получаю то же сообщение:

==59123== 176 bytes in 2 blocks are definitely lost in loss record 8,040 of 8,630
==59123==    at 0x483BE63: operator new(unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==59123==    by 0x6430849: QLayoutPrivate::createWidgetItem(QLayout const*, QWidget*) (qlayout.cpp:200)
==59123==    by 0x6431AA0: QLayout::addWidget(QWidget*) (qlayout.cpp:236)
==59123==    by 0x7DA967: Dialogs::Dialog_multistep::onButtonAddStep_clicked() (dialog_multistep.cpp:419)
==59123==    by 0x7E8B13: QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (Dialogs::Dialog_multistep::*)()>::call(void (Dialogs::Dialog_multistep::*)(), Dialogs::Dialog_multistep*, void**) (qobjectdefs_impl.h:152)
==59123==    by 0x7E8A87: void QtPrivate::FunctionPointer<void (Dialogs::Dialog_multistep::*)()>::call<QtPrivate::List<>, void>(void (Dialogs::Dialog_multistep::*)(), Dialogs::Dialog_multistep*, void**) (qobjectdefs_impl.h:185)
==59123==    by 0x7E89B4: QtPrivate::QSlotObject<void (Dialogs::Dialog_multistep::*)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (qobjectdefs_impl.h:414)
==59123==    by 0x9284CB5: call (qobjectdefs_impl.h:394)
==59123==    by 0x9284CB5: QMetaObject::activate(QObject*, int, int, void**) (qobject.cpp:3774)
==59123==    by 0x64FAFF1: QAbstractButton::clicked(bool) (moc_qabstractbutton.cpp:312)
==59123==    by 0x64FB1F3: QAbstractButtonPrivate::emitClicked() (qabstractbutton.cpp:414)
==59123==    by 0x64FCD8D: QAbstractButtonPrivate::click() (qabstractbutton.cpp:407)
==59123==    by 0x64FCEE4: QAbstractButton::mouseReleaseEvent(QMouseEvent*) (qabstractbutton.cpp:1011)

Но в FlowLayout у меня есть деструктор с:

void FlowLayout::clear()
{
    QLayoutItem* item;
    while ((item = takeAt(0)))
    {
        delete item->widget();
    }
}

Я не понимаю, где утечка.

Я ценю любое предложение. Спасибо

1 Ответ

0 голосов
/ 03 мая 2020

Я нашел проблему. Как я уже писал, я использовал класс FlowLayout, взятый из известного примера (Qt). Метод clear делает:

void FlowLayout::clear()
{
    QLayoutItem* item;
    while ((item = takeAt(0)))
    {
        delete item->widget();
    }
}

, но QLayoutItem возвращает nullptr в методе QLayoutItem :: widget () .

Возможно, потому что QLayoutItem является базовым классом и должен быть получен.

...