最近项目遇到了一个bug,压力测试ui总会崩溃,gdb调试未果,跑到了库函数,无从查起:

(gdb)bt

#0 0x4146b1e4 in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&,QPoint const&, int, QPainter*, QWidgetBackingStore*) () from/qt/lib/libQt5Widgets.so.5

#1 0x4146bb70 in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*,QList<QObject*> const&, int, QRegion const&, QPoint const&,int, QPainter*, QWidgetBackingStore*) ()

from /qt/lib/libQt5Widgets.so.5

#2 0x4146b22c in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&,QPoint const&, int, QPainter*, QWidgetBackingStore*) () from/qt/lib/libQt5Widgets.so.5

#3 0x41443918 in QWidgetBackingStore::sync() () from /qt/lib/libQt5Widgets.so.5

#4 0x41462c9c in QWidgetPrivate::syncBackingStore() () from/qt/lib/libQt5Widgets.so.5

#5 0x4146de64 in QWidget::event(QEvent*) () from /qt/lib/libQt5Widgets.so.5

#6 0x41436a00 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from/qt/lib/libQt5Widgets.so.5

#7 0x4143a590 in QApplication::notify(QObject*, QEvent*) () from/qt/lib/libQt5Widgets.so.5

#8 0x00922918 in ?? ()

#9 0x00922918 in ?? ()

Backtracestopped: previous frame identical to this frame (corrupt stack?)

(gdb)

后来发现问题是qt中使用delete出错,

if(p){

delete p;  // 修改为: p->deletelater();

p = NULL;// 这里必须置为NULL,否则依然会出错(delete后置空是一个非常好的习惯)

}

查阅的参考资料如下:

http://blog.csdn.net/dbzhang800/article/details/6300025http://my.oschina.net/u/566875/blog/306299

摘录其中一文片段如下:

QT有一套回收内存的机制,主要的规则如下:

1、所有继承自QOBJECT类的类,如果在new的时候指定了父亲,那么它的清理时在父亲被delete的时候delete的,所以如果一个程序中,所有的QOBJECT类都指定了父亲,那么他们是会一级级的在最上面的父亲清理时被清理,而不用自己清理;(注:这里是在new出来对象的时候,这样依靠QObject释放的内存一点问题没有,如果以下这种起情况,那么程序会崩溃。

QObject derver;
QObject base;
derver.setParent(&base);

儿子和父亲都是栈空间上,释放内存时候,先释放父亲,释放父亲空间的时候,已经把儿子的内存释放了,当释放儿子的内存的是否,会出现内存错误,因为儿子被释放了两次)

2、程序通常最上层会有一个根的QOBJECT,就是放在setCentralWidget()中的那个QOBJECT,这个QOBJECT在 new的时候不必指定它的父亲,因为这个语句将设定它的父亲为总的QAPPLICATION,当整个QAPPLICATION没有时它就自动清理,所以也无需清理。

3、如果我们自己释放掉设置QObject为自己父亲的类对象,那个指向的父亲的QObject会从自己的儿子列表中把这个儿子删除掉,就不会出现儿子的内存会被释放两次,如果我们要删除有这种关系的QObject类的话,正常情况,这样它会将这个儿子移出它的列表,并且重新构建显示内容,但是直接这样做时有风险的!

4、当一个QOBJECT正在接收事件队列时如果中途被你DELETE掉了,就会出现问题了,所以QT中建议大家不要直接DELETE掉一个 QOBJECT,如果一定要这样做,要使用QOBJECT的deleteLater()函数,它会让所有事件都发送完一切处理好后马上清除这片内存,而且就算调用多次的deletelater也不会有问题。

5、QT不建议在一个QOBJECT 的父亲的范围之外持有对这个QOBJECT的指针,因为如果这样外面的指针很可能不会察觉这个QOBJECT被释放,会出现错误,如果一定要这样,就要记住你在哪这样做了,然后抓住那个被你违规使用的QOBJECT的destroyed()信号,当它没有时赶快置零你的外部指针。当然我认为这样做是及其麻烦也不符合高效率编程规范的,所以如果要这样在外部持有QOBJECT的指针,建议使用引用或者用智能指针,如QT就提供了智能指针针对这些情况,见最后一条。

6、QT中的智能指针封装为QPointer类,所有QOBJECT的子类都可以用这个智能指针来包装,很多用法与普通指针一样

(某些内存泄露的检测工具会认为QT的程序因为这种方式存在内存泄露,大家不必理会)

还有一个内存泄漏的问题:

class ReadoutDisplay : public QWidget
{
Q_OBJECT
public:
......
private: QGridLayout *m_Gridlayout;
int m_no_of_rows;
int m_no_of_col;
}; ReadoutDisplay::ReadoutDisplay(QWidget *parent, QString type) : QWidget(parent){
m_type = type;
m_Gridlayout = new QGridLayout;
  .......
}

泄漏的原因是这里在类中声明的了一个类对象指针,在成员函数中分配了空间,但是没有在成员函数中释放,解决的办法是在析构函数中检查释放:

ReadoutDisplay::~ReadoutDisplay()
{
if(m_Gridlayout)
{
delete m_Gridlayout;
m_Gridlayout = NULL; // once we delete a pointer, it was highly recommended
}
}
 转自:http://blog.csdn.net/zzwdkxx/article/details/49804313
 

Qt中delete的问题的更多相关文章

  1. Qt中内存泄露和退出崩溃的问题 delete

    Qt中帮程序员做了一些内存回收的事情,但正因为这些反而让对此不熟悉的人会屡屡犯错. 收录一篇不错的文章: 在C++中学习过程中,我们都知道: delete 和 new 必须 配对使用(一 一对应):d ...

  2. qt中ui的 使用介绍

    1.什么是ui?ui通常是用Qt 设计师设计出来的界面文件的后缀.通常情况下ui是一个指向这个界面类的指针.ui-> 一般就是用来访问这个界面类里面的控件.例如你的ui文件里有一个叫okButt ...

  3. 第47课 Qt中的调色板

    1. QPalette类 (1)QPalette类提供了绘制QWidget组件的不同状态所使用的颜色. (2)QPalette对象包含了3个状态的颜色描述 ①激活颜色组(Active):组件获得焦点使 ...

  4. 第30课 Qt中的文本编辑组件

    1. 3种常用的文本编辑组件的比较 单行文本支持 多行文本支持 自定义格式支持 富文本支持 QLineEdit (单行文本编辑组件) Yes No No No QPlainTextEdit (多行普通 ...

  5. Qt中QObject中的parent参数

    今天写了一个小程序,验证了带参的构造函数中参数parent的作用. 在MainWindow中声明一个QDialog类型的指针,在MainWindow中对它进行初始化.我采用了两种初始化方式,一种是带参 ...

  6. QT中显示GIF图片

    在QT中要显示GIF图片,不能通过单单的添加部件来完成. 还需要手动的编写程序. 工具:QT Creator 新建一个工程,我们先在designer中,添加一个QLabel部件. 如下图: 将QLab ...

  7. Qt中的键盘事件,以及焦点的设置(比较详细)

    Qt键盘事件属于Qt事件系统,所以事件系统中所有规则对按键事件都有效.下面关注点在按键特有的部分: focus 一个拥有焦点(focus)的QWidget才可以接受键盘事件.有输入焦点的窗口是活动窗口 ...

  8. QT中关闭应用程序和窗口的函数(quit(),exit()以及close()的区别)

    使用QT编辑界面,其中带来很大方便的一点就是Qt中自带丰富的.种类齐全的类及其功能函数,程序员可以在编辑程序的过程中简单地直接调用.关于窗口关闭的操作,在这里指出常用的三个槽,即quit(),exit ...

  9. 6.关于QT中的内存管理,动态的制作,动态库的调用,静态库的制作

     一  QT的内存管理 1  QT中的内存管理是QObject来管理的 2  QT中的内存管理没有cocos2dx中的引用计数 3  组件能够指定父对象 QTimer *timer = QTime ...

随机推荐

  1. I/O复用 - 各种不同的IO模型

    一.概述 我们看到上面的TCP客户同时处理两个输入:标准输入和TCP套接字.我们遇到的问题就是在客户阻塞于(标准输入上的)fgets调用期间,服务器进程会被杀死.服务器TCP虽然正确地给客户TCP发送 ...

  2. vim 折叠

    zR 打开全部折叠 zr 打开当前折叠 zM 关闭全部折叠 zm 关闭当前折叠

  3. 如何查看域名解析是否生效--windows命令

  4. 在windows下部署Redis 当作系统服务器自动启动

    部署Redis 其实Redis是可以安装成windows服务的,开机自启动,命令如下: redis-server --service-install redis.windows.conf 安装完之后, ...

  5. MongoDB索引原理

    转自:http://www.mongoing.com/archives/2797 为什么需要索引? 当你抱怨MongoDB集合查询效率低的时候,可能你就需要考虑使用索引了,为了方便后续介绍,先科普下M ...

  6. iptables的自定义链--子链

    我个人理解:子链的作用就是为了减少重复设置,有的时候可能对数据包进行一系列的处理,而且还被多种规则引用.这样就可以设置成子链,一起跳转过去处理. -j subchain 子链用-N来创建. iptab ...

  7. mybatis 一二事(1) - 简单介绍

    mybatis呢是一个orm数据库框架,非常适合新人学,门槛相对较低 本人呢曾经是先做的hibernate,后接触的mybatis,接触mabatis前我比较抵触,为啥呢, 当时喜欢hibernate ...

  8. Diamond 3.5简易教程(一)------工程的建立

    测试环境(win10 x64 软件Diamond 3.5 x64) 软件下载地址:http://files.latticesemi.com/Diamond/3.5/3.5.0.102_Diamond_ ...

  9. linux 调试利器gdb, strace, pstack, pstree, lsof

    1) 如何使用strace+pstack利器分析程序性能? http://www.cnblogs.com/bangerlee/archive/2012/04/30/2476190.html 此文有详细 ...

  10. Linux下NDK的配置

    vim ~/.bashrc 在文件末尾添加如图两行代码 写下来方便复制export NDKROOT=/usr/ndk/android-ndk-r12bexport PATH=$NDKROOT:$PAT ...