posts - 311, comments - 0, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

(搬运工)浅谈QT的内存回收机制

Posted on 2011-06-01 15:09 点点滴滴 阅读(2412) 评论(0)  编辑 收藏 引用 所属分类: 02 编程语言

初学QT。我本人认为QT更是一种艺术的体现,而非简单的当作一个物品开看待。体现了人类思想的伟大。就这点而言,中国人恰恰就缺少这种创建型艺术细胞。或者说是,国内缺少这种艺术创建的氛围。

   以下文章均为闲聊。并无技术的严谨性。关于其中的内容,可能存在错误。请指正。

  

   C++, Pascal,语言要求必须明确内存的作用域,并且对创建的内存区域。由程序员删除delete。虽然存在自动模式,但并不先进

   Java, SmallTalk,语言则可进行内存碎片的自动查找分析,动态的删除无用内存区域。从而可以使程序员专注于程序逻辑的开发。而无须在即系统问题。

   对于内存的释放存在3中方法:

       1 - Let the creating object delete its child objects. 创建并删除

       2 - Let the last object to handle an object delete it.最后处理

       3 - Don't care about memory and forget about it.      无须在意

   对于第三种方法,我们称之为"bug"。将会造成内存的溢出。 对于程序员应该熟悉前2种方法。

   但QT则采用一种更高级的内存管理机制.

   1 - QPointer  可以监控空间的分配状况。以下程序,请自行分析

         QDate *mydate=new QDate(QDate::currentDate());
         QPointer<QDate> mypointer=mydata;
         mydate->year();    // -> 2005
         mypointer->year(); // -> 2005

        delete mydate;

        if(mydate==0) printf("clean pointer");                       //mode 1
        else printf("dangling pointer");
        // -> "dangling pointer"

        if(mypointer.isNull()) printf("clean pointer");             //mode 2
        else printf("dangling pointer");
        // -> clean pointer

   2 - 内存处理机制   QObjectCleanupHandler

      姑且略过

   3 - 碎片处理

       存在几种简单的碎片处理机制。

       a.计数器模式类似于压栈

       b.父窗口的自动回收

       c.自我的回收

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

下面才是最重要的(转载)

 在栈上用new分配的内存,为什么没有用delete释放?

从HelloQt说起

#include <qapplication.h>
#include 
<qlabel.h>
int main( int argc, char **argv ){
    QApplication app( argc, argv );   
    QLabel 
*label=new QLabel(“Hello QT!”,0);
    app.setMainWidget( label );
    label
->show();
    
return a.exec();
}



这里label是new出来的一个指针变量,也就是在栈上申请的内存,在C++语言里,明确过,在栈上分配的内存是必须认为的用delete释放的,防止内存泄露。这里为什么没有呢。后来看到有的QT程序也有明确使用delete释放内存的。这里越发不解了。后来,查到原来是QT扩展了C++,如果指针对象有父对象时,可以不用显式释放内存。我们需要显式释放的是那些没有父对象的孤立的指针。但上面这个例子并没有继承父对象,注意第二个指针,指向父对象的指针参数为0,即没有父对象,但是setMainWidget把它设为了主窗口部件,它就和程序同步了,当程序退出的时候自动释放,孩子对象的释放也是如此,在QT中扩展了C++ ,如果父亲对象无效时,子对象自动释放分配的内存。