Ошибка памяти, библиотека Qt

344
28 июня 2017, 00:03

Следующий код создает окно и при закрытии:

#include <QApplication>
#include <QTextEdit>
#include <QPushButton>
#include <QVBoxLayout>
int main(int argc, char **argv) {
    QApplication app(argc, argv);
    QTextEdit textEdit;
    QPushButton quitButton("Exit");
    QObject::connect(&quitButton, SIGNAL(clicked()), qApp, SLOT(quit()));
    QVBoxLayout layout;
    layout.addWidget(&textEdit);
    layout.addWidget(&quitButton);
    QWidget window;
    window.setLayout(&layout);
    window.show();
    return app.exec();
}

вызывает следующую ошибку: QtCalc(47351,0x7fffce3e73c0) malloc: *** error for object 0x7fff5ea469f0: pointer being freed was not allocated *** set a breakpoint in malloc_error_break to debug

В чем проблема?

Answer 1

Оконный виджет попытался уничтожить дочерние widget-ы и макет так, будто они размещены в куче. На самом же деле всё размещено на стеке, а потому стандартная библиотека пресекла эту попытку и аварийно завершила приложение.

Данная же попытка была вызвана тем, что любой QObject (потомком которого является QWidget) обязуется прибирать за собой все дочерние объекты, освобождая от этой обязанности автора программы.

Для решения проблемы можно воспользоваться тем фактом, что любой дочерний QObject при своём уничтожении передаёт сигнал родителю, и тот убирает удаляемый объект из своего списка во избежание повторного удаления.

То есть будь QTextEdit, QPushButton и QVBoxLayout уничтожены до QWidget, последний не стал бы трогать уже уничтоженные объекты, и программа завершилась бы нормальным путём. Для достижения этого эффекта достаточно поместить объявление QWidget window; перед всем тем, что будет в него позднее добавлено:

// ...
int main(int argc, char **argv) {
    QApplication app(argc, argv);
    QWidget window;         // <---
    QTextEdit textEdit;
   // ...
}

Это сработает, потому что локальные переменные (и члены класса) всегда уничтожаются в порядке, обратном тому, в котором они создавались.

READ ALSO
Использование std::find_if для массива (STL)

Использование std::find_if для массива (STL)

Мне необходимо обработать массив и выявить индекс элемента, значение которого меньше определенного(Если таких элементов несколько, то узнать...

229
C++ Qt Многопоточный TCP сервер

C++ Qt Многопоточный TCP сервер

Нужно написать сервер для приёма данных от разных по типу устройств с подтверждением приёмаУстройства присылают разные данные и алгоритм...

410
Рендер 2D изображения в текстуру OpenGL

Рендер 2D изображения в текстуру OpenGL

Имеется Framebuffer object с прикреплённой текстурой и буффером глубиныСначала происходит отрисовка в буффер, а потом этот буффер выводится на экран

328
Как использовать общую память для двух процессов С линукс

Как использовать общую память для двух процессов С линукс

Нужно сделать общим для нескольких процессов массив структурРешил сделать так: один из процессов выделяет общий блок памяти с помощью shmget,...

267