找回密码
 立即注册
收起左侧

QT 界面内存泄漏问题

5
回复
10521
查看
[复制链接]
累计签到:3 天
连续签到:1 天
来源: 2016-9-28 16:29:01 显示全部楼层 |阅读模式
10Qter豆

第一次创建一个窗口并返回后发现内存增加了一点(几百kb左右),之后创建并返回内存就不再增加了。
有没哪位大神知道这个原理啊?

ps:之前在Ubuntu 上发现的这个问题,以为是linux的内存管理机制(cache)。但没想到在windows上也有这个问题

类似问题:
http://www.qter.org/forum.php?mod=viewthread&tid=1030
http://bbs.csdn.net/topics/390341517


测试代码:
main.cpp
  1. #include "mainwindow.h"
  2. #include <QApplication>
  3. #include <QLabel>

  4. int main(int argc, char *argv[])
  5. {
  6.     QApplication a(argc, argv);
  7.     MainWindow w;
  8.     w.show();

  9.     return a.exec();
  10. }
复制代码
mainwindow.cpp
  1. #include "mainwindow.h"
  2. #include "nextpage.h"

  3. #include <QVBoxLayout>
  4. #include <QPushButton>
  5. #include <QLabel>
  6. #include <QDebug>
  7. #include <QObjectCleanupHandler>

  8. MainWindow::MainWindow(QWidget *parent) :
  9.     QWidget(parent)
  10. {
  11.     qDebug() << "MainWindow::MainWindow";
  12. }

  13. MainWindow::~MainWindow()
  14. {
  15.     qDebug() << "MainWindow::~MainWindow";
  16. }

  17. void MainWindow::showEvent(QShowEvent *)
  18. {
  19.     qDebug() << "MainWindow::showEvent";
  20. //    QObjectCleanupHandler *cleaner=new QObjectCleanupHandler;
  21.     QVBoxLayout *vbox = new QVBoxLayout(this);
  22.     QPushButton *btn  = new QPushButton("add text",this);
  23.     QPushButton *btn2  = new QPushButton("creat page",this);
  24.     QPushButton *btn3  = new QPushButton("deletLater page",this);
  25.     QPushButton *btn4  = new QPushButton("delet all",this);

  26.     QLabel *label = new QLabel(this);
  27.     label->setPixmap(QPixmap(":/images/media.svg"));

  28.     vbox->addWidget(btn);
  29.     vbox->addWidget(btn2);
  30.     vbox->addWidget(btn3);
  31.     vbox->addWidget(btn4);
  32.     vbox->addWidget(label);
  33.     vbox->addStretch(1);


  34.     connect(btn,&QPushButton::clicked,[this,vbox](){
  35.         vbox->addWidget(new QLabel("the add label"));
  36.     });

  37.     connect(btn2,&QPushButton::clicked,[this]{
  38.         page = new NextPage();
  39. //        cleaner->add(page);
  40.         page->resize(this->size());
  41.         page->show();
  42.     });

  43.     connect(btn3,&QPushButton::clicked,[this]{
  44.         if(page){
  45.             qDebug("deletlater page");
  46.             page->deleteLater();
  47.             page = NULL;
  48.         }
  49.     });
  50.     connect(btn4,&QPushButton::clicked,[this]{
  51. //        if(cleaner){
  52.             qDebug("delet all");
  53. //            cleaner->deleteLater();
  54. //        }
  55.     });
  56. }


复制代码
nextpage.cpp
  1. #include "nextpage.h"
  2. #include <QVBoxLayout>
  3. #include <QPushButton>
  4. #include <QDebug>

  5. NextPage::NextPage(QWidget *parent) : QWidget(parent)
  6. {

  7. }

  8. void NextPage::showEvent(QShowEvent *)
  9. {
  10.     qDebug() << "NextPage::showEvent";
  11.     QVBoxLayout *vbox = new QVBoxLayout(this);
  12.     QPushButton *btn  = new QPushButton("add image ",this);
  13.     QPushButton *btn2  = new QPushButton("this deletLater",this);

  14.     TLabel *label = new TLabel(this);
  15.     label->setPixmap(QPixmap(":/images/media.svg"));

  16.     vbox->addWidget(btn);
  17.     vbox->addWidget(btn2);
  18.     vbox->addWidget(label);

  19.     vbox->addStretch(1);


  20.     for(int i=0;i< 100; i++){
  21.         TLabel *label3 = new TLabel(this);
  22.         label3->setPixmap(QPixmap(":/images/media.svg"));
  23.         vbox->addWidget(label3);
  24.     }

  25.     connect(btn,&QPushButton::clicked,[this,vbox](){
  26.         TLabel *label1 = new TLabel(this);
  27.         label1->setPixmap(QPixmap(":/images/media.svg"));
  28.         vbox->addWidget(label1);
  29.     });

  30.     connect(btn2,&QPushButton::clicked,[this]{
  31.         this->hide();
  32.         this->deleteLater();
  33.     });
  34. }

  35. TLabel::TLabel( QWidget *parent) :
  36.     QLabel(parent)
  37. {
  38. }

  39. TLabel::~TLabel()
  40. {
  41.     qDebug() << "TLabel::~TLabel";
  42. }
复制代码
头文件:
mainwindow.h
  1. #ifndef MAINWINDOW_H
  2. #define MAINWINDOW_H

  3. #include <QWidget>

  4. class NextPage;

  5. class MainWindow : public QWidget
  6. {
  7.     Q_OBJECT

  8. public:
  9.     explicit MainWindow(QWidget *parent = 0);
  10.     ~MainWindow();

  11.     void showEvent(QShowEvent *);

  12. private:
  13.     NextPage *page;
  14. };

  15. #endif // MAINWINDOW_H
复制代码
nextpage.h
  1. #ifndef NEXTPAGE_H
  2. #define NEXTPAGE_H

  3. #include <QWidget>
  4. #include <QLabel>

  5. class TLabel :public QLabel
  6. {
  7.     Q_OBJECT
  8. public:
  9.     explicit TLabel(QWidget *parent =0);
  10.     ~TLabel();
  11. };

  12. class NextPage : public QWidget
  13. {
  14.     Q_OBJECT
  15. public:
  16.     explicit NextPage(QWidget *parent = 0);

  17.     void showEvent(QShowEvent *);

  18. signals:

  19. public slots:
  20. };

  21. #endif // NEXTPAGE_H
复制代码

回复

使用道具 举报

累计签到:1572 天
连续签到:1 天
2016-9-30 16:57:43 显示全部楼层
建议自己研究研究,别把程序写成这样,先写个helloworld,然后添加内容,自己看看研究下!
回复

使用道具 举报

累计签到:4 天
连续签到:1 天
2016-10-3 19:13:03 显示全部楼层
这个是什么问题?没明白
回复

使用道具 举报

累计签到:3 天
连续签到:1 天
2016-10-11 14:03:57 显示全部楼层
参考资料:
1.large-scale multi-thread-capable libraries 的内存缓存机制
http://stackoverflow.com/questio ... ithout-memory-leaks

2.Windows 的head 碎片
http://www.qtcentre.org/threads/ ... ghlight=memory+leak
回复

使用道具 举报

累计签到:410 天
连续签到:1 天
2016-10-26 09:08:36 显示全部楼层
showEvent事件里面,你每次都去new。
肯定有问题啊。。一般都是在构造函数里面new。
回复

使用道具 举报

累计签到:3 天
连续签到:1 天
2016-11-1 11:29:47 显示全部楼层
a408815041 发表于 2016-10-26 09:08
showEvent事件里面,你每次都去new。
肯定有问题啊。。一般都是在构造函数里面new。 ...

show里面new的好处在于控件的实时创建,但这里确实应该加个inited属性(bool)防止重复。但这不是重点,通过log可以看到没有重复调用showevent。
我的问题类似:"QWidget  *w = new QWidget();w->show();w->deleteLater();"这样一个简单的创建与删除过程中也会导致的“内存泄漏”是什么原因产生的
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

公告
可以关注我们的微信公众号yafeilinux_friends获取最新动态,或者加入QQ会员群进行交流:190741849、186601429(已满) 我知道了