400 / 300 / 60
Регистрация: 29.05.2018
Сообщений: 947
1

Как избавиться от утечки памяти при переключении между виджетами?

29.05.2018, 15:25. Показов 876. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Задача:
1) Показать кнопку в Form1.
2) По нажатию на кнопку переключиться в такую же форму с кнопкой Form2.
3) Аналогично по нажатию кнопки в Form2 переключиться на Form1.
4) И так сколько угодно раз.

Вот сам код:

main.cpp
======
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "form1.h"
#include "form2.h"
#include <QApplication>
 
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Form1 f1;
    Form2 f2;
 
    f1.show();
 
    return a.exec();
}
form1.h
======
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ifndef FORM1_H
#define FORM1_H
 
#include "ui_form1.h"
 
class Form1 : public QWidget, private Ui::Form1
{
    Q_OBJECT
 
public:
    explicit Form1(QWidget *parent = 0);
 
public slots:
    void showForm2();
};
 
#endif // FORM1_H
form2.h
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ifndef FORM2_H
#define FORM2_H
 
#include "ui_form2.h"
 
class Form2 : public QWidget, private Ui::Form2
{
    Q_OBJECT
 
public:
    explicit Form2(QWidget *parent = 0);
 
public slots:
    void showForm1();
};
 
#endif // FORM2_H
form1.cpp
=======
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "form1.h"
#include "form2.h"
 
Form1::Form1(QWidget *parent) :
    QWidget(parent)
{
    setupUi(this);
 
    connect(pushButton, SIGNAL(clicked(bool)), this, SLOT(showForm2()));
}
 
void Form1::showForm2()
{
    Form2* form2 = new Form2;
    form2->show();
    hide();
}
form2.cpp
=======
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "form2.h"
#include "form1.h"
 
Form2::Form2(QWidget *parent) :
    QWidget(parent)
{
    setupUi(this);
 
    connect(pushButton, SIGNAL(clicked(bool)), this, SLOT(showForm1()));
}
 
void Form2::showForm1()
{
    Form1* form1 = new Form1;
    form1->show();
    hide();
}
Код отрабатывает всё правильно, кроме одного: при каждой итерации "отъедается" оперативная память.
Как решить данную проблему?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
29.05.2018, 15:25
Ответы с готовыми решениями:

Как избавиться от расстояния между виджетами
Вроде всё перепробовал, а не получается избавиться от расстояния между paintwidget-ами... //...

Как избавиться от утечки памяти через 'string' в D5?
Всем доброго времени суток! Кто знает — есть ли какие нибудь средства принудительного...

Как избежать утечки памяти при данном выделении памяти?
Всем привет. В проекте MFC делаю следующие манипуляции MY_STRUCT *ms = new MY_STRUCT();...

Как избежать утечки памяти при добавлении элемента в TSet
Здравствуйте. Подскажите, пожалуйста, как избежать утечки памяти при добавлении элемента в...

11
278 / 87 / 37
Регистрация: 10.06.2015
Сообщений: 261
29.05.2018, 15:36 2
Как избавиться от утечки памяти при переключении между виджетами? - C++ Qt
Ну дак ты не переключаешься, а каждый раз новый виджет создаешь, пряча старый.
0
1664 / 1133 / 80
Регистрация: 21.08.2008
Сообщений: 4,734
Записей в блоге: 1
29.05.2018, 19:20 3
Работа с 2 и более ui формами
2
6 / 6 / 2
Регистрация: 29.05.2018
Сообщений: 13
29.05.2018, 20:36 4
У тебя не переключение, а создание нового виджета, к томуже при создании неуказываешь предка :Form1* form1 = new Form1(this);

Добавлено через 6 минут
Если не указать предка то Qt не знает когда нужно освободить память.
0
487 / 365 / 93
Регистрация: 10.03.2011
Сообщений: 1,513
Записей в блоге: 5
30.05.2018, 09:15 5
Самое тупое решение - заменить hide() на deleteLater(). Оно же самое худшее.
0
400 / 300 / 60
Регистрация: 29.05.2018
Сообщений: 947
30.05.2018, 11:48  [ТС] 6
Цитата Сообщение от oxotnik Посмотреть сообщение
Работа с 2 и более ui формами
Добавил после setupUi(this); :
C++ (Qt)
1
setAttribute(Qt::WA_DeleteOnClose, true);
и заменил hide(); на close(); в обоих реализациях. От утечки памяти избавился, спасибо!

Теперь другая проблема появилась: в консоли приложения в Qt Creator при запуске ошибки:
Windows Batch file
1
2
3
4
Запускается G:\...\Form1Form2.exe...
Программа неожиданно завершилась.
Процесс был завершён принудительно.
G:/.../Form1Form2.exe аварийно завершился.
0
487 / 365 / 93
Регистрация: 10.03.2011
Сообщений: 1,513
Записей в блоге: 5
30.05.2018, 12:18 7
Ну, жизнь - жестокая штука. Для начала попробуй не делать объектов QObject на стеке
0
6 / 6 / 2
Регистрация: 29.05.2018
Сообщений: 13
30.05.2018, 16:12 8
Что говорит отладчик, на какой строке останавливается при вылете?
Не видя кода остается только ванговать.
0
487 / 365 / 93
Регистрация: 10.03.2011
Сообщений: 1,513
Записей в блоге: 5
30.05.2018, 19:59 9
Объект создаётся на стеке - у него нельзя дёргать методы самоликвидации. Сразу видно, что клиент слез с жабы.
0
400 / 300 / 60
Регистрация: 29.05.2018
Сообщений: 947
31.05.2018, 10:23  [ТС] 10
Цитата Сообщение от Hazmit Посмотреть сообщение
Что говорит отладчик, на какой строке останавливается при вылете?
Не видя кода остается только ванговать.
Ответ отладчика на скрине, код в zip-архиве.
Миниатюры
Как избавиться от утечки памяти при переключении между виджетами?  
Вложения
Тип файла: zip Form1Form2_.zip (3.5 Кб, 3 просмотров)
0
6 / 6 / 2
Регистрация: 29.05.2018
Сообщений: 13
02.06.2018, 08:58 11
У тебя рекурсивное создание форм, "неправильно все это".

Укажи false
C++ (Qt)
1
 setAttribute(Qt::WA_DeleteOnClose, false);
И добавь после конструктора.
form1.h
C++ (Qt)
1
~Form1();
form2.h
C++ (Qt)
1
~Form2();
form1.cpp
C++ (Qt)
1
Form1::~Form1(){}
form2.cpp
C++ (Qt)
1
Form2::~Form2(){}
Так будто бы не ругается на утечку памяти. Может описал бы, по конкретней, какую цель ты при следуешь.

Добавлено через 15 минут
Добавь библиотеку <QtDebug> чтобы отслеживать создание и удаление классов.
form1.h
Кликните здесь для просмотра всего текста
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef FORM1_H
#define FORM1_H
 
#include "ui_form1.h"
 
class Form1 : public QWidget, private Ui::Form1
{
    Q_OBJECT
 
public:
    explicit Form1(QWidget *parent = 0);
    ~Form1();
 
public slots:
    void showForm2();
};
 
#endif // FORM1_H


form1.cpp
Кликните здесь для просмотра всего текста
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include "form1.h"
#include "form2.h"
#include <QtDebug>
 
Form1::Form1(QWidget *parent) :
    QWidget(parent)
{
    setupUi(this);
 
    setAttribute(Qt::WA_DeleteOnClose, false);
 
    connect(pushButton, SIGNAL(clicked(bool)), this, SLOT(showForm2()));
    qDebug()<<"Create new Form1";
}
Form1::~Form1()
{
 qDebug()<<"Delete Form1";
}
void Form1::showForm2()
{
    Form2* form2 = new Form2/*(this)*/;
    form2->show();
    close();
}


form2.h
Кликните здесь для просмотра всего текста
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ifndef FORM2_H
#define FORM2_H
 
#include "ui_form2.h"
 
class Form2 : public QWidget, private Ui::Form2
{
    Q_OBJECT
 
public:
    explicit Form2(QWidget *parent = 0);
    ~Form2();
public slots:
    void showForm1();
};
 
#endif // FORM2_H


form2.cpp
Кликните здесь для просмотра всего текста
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include "form2.h"
#include "form1.h"
#include <QtDebug>
 
Form2::Form2(QWidget *parent) :
    QWidget(parent)
{
    setupUi(this);
 
    setAttribute(Qt::WA_DeleteOnClose, false);
 
    connect(pushButton, SIGNAL(clicked(bool)), this, SLOT(showForm1()));
    qDebug()<<"Create new Form2";
}
Form2::~Form2()
{
   qDebug()<<"Delete Form1";
}
void Form2::showForm1()
{
    Form1* form1 = new Form1;
    form1->show();
    close();
}
0
400 / 300 / 60
Регистрация: 29.05.2018
Сообщений: 947
07.06.2018, 14:34  [ТС] 12
Победил. Всем спасибо!
main.cpp
Кликните здесь для просмотра всего текста
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
#include "form1.h"
#include <QApplication>
 
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Form1 w;
    w.show();
 
    return a.exec();
}


form1.h
Кликните здесь для просмотра всего текста
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#ifndef FORM1_H
#define FORM1_H
 
#include "ui_form1.h"
#include "form2.h"
 
namespace Ui {
class Form1;
}
 
class Form1 : public QWidget
{
    Q_OBJECT
 
public:
    explicit Form1(QWidget *parent = 0);
    ~Form1();
 
private slots:
    void on_pushButton_clicked();
 
private:
    Ui::Form1* ui;
    Form2* form2;
};
 
#endif // FORM1_H


form1.cpp
Кликните здесь для просмотра всего текста
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include "form1.h"
 
Form1::Form1(QWidget *parent) :
    QWidget(parent), ui(new Ui::Form1)
{
    ui->setupUi(this);
    form2 = new Form2();
    connect(form2, &Form2::firstForm, this, &Form1::show);
}
 
Form1::~Form1()
{
    delete ui;
}
 
void Form1::on_pushButton_clicked()
{
    form2->show();
    this->close();
}


form2.h
Кликните здесь для просмотра всего текста
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#ifndef FORM2_H
#define FORM2_H
 
#include "ui_form2.h"
 
namespace Ui {
class Form2;
}
 
class Form2 : public QWidget
{
    Q_OBJECT
 
public:
    explicit Form2(QWidget *parent = 0);
    ~Form2();
 
signals:
    void firstForm();
 
private slots:
    void on_pushButton_clicked();
 
private:
    Ui::Form2* ui;
};
 
#endif // FORM2_H


form2.cpp
Кликните здесь для просмотра всего текста
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "form2.h"
 
Form2::Form2(QWidget *parent) :
    QWidget(parent), ui(new Ui::Form2)
{
    ui->setupUi(this);
}
 
Form2::~Form2()
{
    delete ui;
}
 
void Form2::on_pushButton_clicked()
{
    this->close();
    emit firstForm();
}
0
07.06.2018, 14:34
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.06.2018, 14:34
Помогаю со студенческими работами здесь

Утечки памяти при использовании ExpandableListView
Всем здравствуйте. Сразу оговорюсь, что проект выполняется на Xamarin.Android. Но т.к. сама...

Как взаимодействовать между виджетами?
Итак, у меня есть куча классов, в которых описываются разные кастомные элементы - немного...

ClientDataSet, Blob утечки памяти при записи в файл
столкнулся с такой ситуацией, есть ClientdataSet в котором есть блоб поле, которое я записываю...

Как избавиться от переполнения памяти при очистке большого html файла?
Всем привет. Имею текстовый фаил объемом 100 мегабайт. В html коде. Там большой набор...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru