zoukankan      html  css  js  c++  java
  • Qt 程序退出时断言错误——_BLOCK_TYPE_IS_VALID(pHead->nBlockUse),由setAttribute(Qt::WA_DeleteOnClose)引起

    最近在学习QT,自己仿写了一个简单的QT绘图程序,但是在退出时总是报错,断言错误:

    报错主要问题在_BLOCK_TYPE_IS_VALID(pHead->nBlockUse),是在关闭窗口时报的错;

    先前考虑是析构函数有问题,重写并且排查相关变量并未发现问题。

    根据报错问题又推测栈调用出现内存溢出,寻找程序中所有的链表和栈调用。未果。

    最后用了最笨的方法,将构造函数中所有变量挨个遍历,最终确定问题出在Qt的setAttribute(Qt::WA_DeleteOnClose)这行代码上。

    网上查询原来Qt初始化时有两种构造方式:

                              当MainWindow   w;  w.show();时,是将窗口对象定义在栈上,

              当MainWindow  *w = new MainWindow ;时,则是定义在堆上。

    而setAttribute函数原型为:void QWidget::setAttribute ( Qt::WidgetAttribute attribute, bool on = true )

    Qt文档解释:Sets the attribute attribute on this widget if on is true; otherwise clears the attribute.

    简单翻译就是:当on为true时,设置当前窗口的状态attribute为开启状态,其他则清除当前attribute状态。

    而关于Qt::WA_DeleteOnClose,从字面意思来看不难猜测是在窗口关闭是调用delete来析构当前窗口指针,可以简单理解成在关闭窗口时执行了delete w;

    但是当前窗口若定义在栈上,w是一个对象而不是指针,显然不正确,而报断言错误的原因则是当程序执行到这里是“w指针"不存在,故而报出断言错误。

     关于堆栈,可以参考:什么是堆栈?它们在哪?

    总结:1、在Qt中有两种内存分配方式(基于C的,一定和C一样啦~),分别是堆分配和栈分配。

       2、当MainWindow   w;  w.show();时,是将窗口对象定义在栈上,

          当MainWindow  *w = new MainWindow ;时,则是定义在堆上。

         3、setAttribute()函数可以设置窗口状态属性,当窗口对象定义在堆上,需要开启Qt::WA_DeleteOnClose状态;而在定义在栈上,开启这个状态则会报错。

       4、写程序养成留下断言的习惯,可以及早发现程序错误,断言真的很好使。

         5、做程序开发,一定要亲力亲为,和大多数事情一样,没有捷径可走。脚踏实地做下去,会有令人欣慰的成果。

                                                2014年11月15日于秦皇岛

  • 相关阅读:
    二叉树还原【前序+中序】【后续+中序】
    字符串中字符的个数和字符序列
    URL中“#” “?” &“”号的作用
    【java】String类和StringBuffer类常用操作
    Java基本开发环境搭建
    LeetCode:Pow(x, n)
    使用DX绘制3D物体时新手常犯错误,看不见物体时可以一一排查
    zlib代码生成
    zlib用法说明
    进程间通信的WM_COPYDATA的使用
  • 原文地址:https://www.cnblogs.com/suanec/p/4098595.html
Copyright © 2011-2022 走看看