Qhash封装之后内存释放问题,求教~

卧听檐雨 2013-01-26 09:11:41
因为工程需要,对QHash进行封装,封装之后,进行Delete,但是内存并不释放,单独对QHash进行测试,发现没有问题,贴出代码,请教各位大神,看看那是哪里的问题~~~~~~
头文件如下:
#ifndef SETTABLE_H
#define SETTABLE_H
#include<QHash>
#include "settings.h"
#include<QHashIterator>
#include<QMutex>
#include"systemlog.h"
#include "gloabletime.h"
class SetTable
{
public:
SetTable();
~SetTable();
//COPY CONSTRUCTURE
SetTable(const SetTable& s);
SetTable& operator = (const SetTable& ); //赋值符重载

bool Add(QString Name ,Settings* Value);
bool Remove(QString Name);
Settings* GetItem(QString Name);

QString GetItemByEquipID(QString EquipID);
QString GetItemByEquipID(QString EquipType,QString EquipAddress);
bool SetItem(QString ClassName,Settings* Value);
bool SetItem(QString ClassName,QString SubClassName,QString OptionName,QString Value );
QHash<QString,Settings*>::const_iterator GetIterator();
void ReleaseResource();
int Count();
private:
QHash<QString,Settings*>*StList;// modify by pointer
};

#endif // SETTABLE_H
构造,析构,copy构造 实现如下:
SetTable::SetTable()
{
this->StList=new QHash<QString,Settings*>();
}
SetTable::~SetTable()
{
this->StList->clear();
this->StList->squeeze();
this->StList->detach();
this->StList->~QHash();
delete this->StList;
StList=NULL;
}

SetTable::SetTable(const SetTable& s)
{
this->StList=new QHash<QString,Settings*>;
* this->StList=*s.StList;
}
SetTable& SetTable::operator =(const SetTable& s)
{
if(this==&s)
{
return *this;
}
else
{
* this->StList=*s.StList;
return *this;
}
}
求指教,求解惑,求答疑~~~~~~~~~~
...全文
1680 40 打赏 收藏 转发到动态 举报
写回复
用AI写文章
40 条回复
切换为时间正序
请发表友善的回复…
发表回复
卧听檐雨 2013-03-02
  • 打赏
  • 举报
回复
引用 39 楼 allencui0313 的回复:
弱弱的问一下。如果有一个。QHash<QWidget*> m_hash; 这个你是怎么释放的?
这是一个存放QWidget指针的hash结构,在析构hash之前,先把指针指向的Widget释放,再析构hash
  • 打赏
  • 举报
回复
弱弱的问一下。如果有一个。QHash<QWidget*> m_hash; 这个你是怎么释放的?
stereoMatching 2013-02-05
  • 打赏
  • 举报
回复
引用 37 楼 ydpro 的回复:
QDomDocument Doc; QString Emsg; int ELine,EColumn; if(!Doc.setContent(&file,&Emsg,&ELine,&EColumn)) { file.close(); Result=false; } 现在的问题是这个了,这个QDomDocument在SetContent之后,内存会被占用,然后很难释放... ……
用同样的方法(34楼)测试看看?我估计是用了pool来控管memory才会造成这种现象
卧听檐雨 2013-02-05
  • 打赏
  • 举报
回复
引用 36 楼 ydpro 的回复:
引用 35 楼 ydpro 的回复:引用 34 楼 stereoMatching 的回复:引用 33 楼 ydpro 的回复:引用 32 楼 stereoMatching 的回复:忘了提醒你,我的环境一切正常 在windows下,运行内存是释放的吗? 这么说,难道是Linux的环境有关,或者说是Linux下的内存管理存在问题吗? 说实话,我也不知道,爱莫能助 如果……
QDomDocument Doc; QString Emsg; int ELine,EColumn; if(!Doc.setContent(&file,&Emsg,&ELine,&EColumn)) { file.close(); Result=false; } 现在的问题是这个了,这个QDomDocument在SetContent之后,内存会被占用,然后很难释放...
卧听檐雨 2013-02-05
  • 打赏
  • 举报
回复
引用 35 楼 ydpro 的回复:
引用 34 楼 stereoMatching 的回复:引用 33 楼 ydpro 的回复:引用 32 楼 stereoMatching 的回复:忘了提醒你,我的环境一切正常 在windows下,运行内存是释放的吗? 这么说,难道是Linux的环境有关,或者说是Linux下的内存管理存在问题吗? 说实话,我也不知道,爱莫能助 如果你确定真的有问题,我可以帮你到该论坛……
按照您的测试方法,用While的方式,内存确实在不断变化,从4.X~5.X之间变化,为什么单次执行不起作用呢~,非要用While的方式才能观察到内存的释放呢
卧听檐雨 2013-02-05
  • 打赏
  • 举报
回复
引用 34 楼 stereoMatching 的回复:
引用 33 楼 ydpro 的回复:引用 32 楼 stereoMatching 的回复:忘了提醒你,我的环境一切正常 在windows下,运行内存是释放的吗? 这么说,难道是Linux的环境有关,或者说是Linux下的内存管理存在问题吗? 说实话,我也不知道,爱莫能助 如果你确定真的有问题,我可以帮你到该论坛发问 能改进Qt的品质对大家都有好处 照你的测……
1.这个我没有Windows环境下的QT,一直在Ubuntu下测试 2.昨天晚上一直再查Linux的内存分配以及环境配置问题,看了这篇文章,linux 内存释放,http://blog.zol.com.cn/2322/article_2321774.html 3.我在Linux下试试看您的测试代码
stereoMatching 2013-02-04
  • 打赏
  • 举报
回复
至于Qt的memory release机制,是基于parent and children的手法 1 : 你的father,children都是QObject 2 : 你的children必须成为father的children 这样一来,father在死亡的时候,就会把地下的children都杀光 你可以把他想像成资料结构的tree 最上层的node(father)死亡前会把底下的nodes(children)都杀了 如果那些nodes底下有children的话他们也会把那些children都杀了 既然QHash不是QObject,那么他就不会被Qt自动回收 memory没有被回收是你的问题,不是Qt的问题
stereoMatching 2013-02-04
  • 打赏
  • 举报
回复
>QHash<QString,Settings*>*StList;// modify by pointer QHash指向的Settings*都要配合一个delete 你还没delete就呼叫clear Settings的pointers所指向的resource在还没 delete前就都被你clear掉了 你这样子memory怎么可能会自动释放? 大幅简化memory管理的方法是RAII 强烈建议你把这东西弄懂,你以后就不会 再为了这些琐碎的memory问题伤透脑筋

std::unique_ptr<QHash<QString, std::unique_ptr<Settings> > > StList;
或std::shared_ptr 不支援shared_ptr或unique_ptr,Qt自己也有提供smart pointer 如果你对smart pointer有疑问,可以另外选个帖子发问 楼主大概没读过meyers的effective series?对于要用c++开发案子的人来说 阅读meyers的书会有很大的帮助,如果你还没读过 请快点跑去书店买回来啃,不是走去买,是跑去买
stereoMatching 2013-02-04
  • 打赏
  • 举报
回复
引用 33 楼 ydpro 的回复:
引用 32 楼 stereoMatching 的回复:忘了提醒你,我的环境一切正常 在windows下,运行内存是释放的吗? 这么说,难道是Linux的环境有关,或者说是Linux下的内存管理存在问题吗?
说实话,我也不知道,爱莫能助 如果你确定真的有问题,我可以帮你到该论坛发问 能改进Qt的品质对大家都有好处 照你的测试方法,就算在win7下memory也不会跟分配memory前完全一样 可能有些resource被放到pool里头? 不过你若是频繁的释放和分配,memory的大小变化会维持在一定的范围内 在release版下,你仔细观察一下memory的变化好了

#include <QtCore>
#include <QtGui>

void memory_alloc_release()
{
    QHash<QString,QHash<QString,QHash<QString,QString> > > Options;
    for(int i=0;i<10;i++)
    {
        QHash<QString,QHash<QString,QString> > Tmp2;

        for(int m=0;m<1000;m++)
        {
            QHash<QString,QString> Tmp1;
            Tmp1.insert(QString::number(m),QString::number(m));
            Tmp2.insert(QString::number(m),Tmp1);
        }
        Options.insert(QString::number(i),Tmp2);
    }

}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    
    while(1){
        memory_alloc_release();    
    }    

    QLabel w;
    w.show();
    
    return a.exec();
}

我的环境下,memory一直在5M~7.XM下变化 memory确实有不断的回收和释放 smart pointer的使用不难 快点掌握他吧,处理上层逻辑的时候 smart pointer会帮你省下很多时间的 至少你以后除错的时候不用再担心有哪里 忘了release resource 我以前用C的时候总是得将忘了release这个 可能性纳入计算,用了smart pointer后我再也不曾 为了这问题而烦恼了
卧听檐雨 2013-02-04
  • 打赏
  • 举报
回复
引用 32 楼 stereoMatching 的回复:
忘了提醒你,我的环境一切正常
在windows下,运行内存是释放的吗? 这么说,难道是Linux的环境有关,或者说是Linux下的内存管理存在问题吗?
stereoMatching 2013-02-04
  • 打赏
  • 举报
回复
忘了提醒你,我的环境一切正常
卧听檐雨 2013-02-04
  • 打赏
  • 举报
回复
引用 28 楼 stereoMatching 的回复:
我也不知道发生了什么事情...可能是QHash用pool管理resource 所以resource暂时没有被释放? 我用的版本是Qt4.8.4,win764bits, mingw4.6.2 到这里去问问题吧,说不定是Qt4.8.1的bug? http://qt-project.org/forums/ 确定是bug而且Qt4.8.4也有一样的问题后可以到这里报告 https:……
如果使用内存池的方式来管理的话,很长时间内,内存都不释放的..... 所以,我一直在说,十分搞不懂Qt的内存管理机制,或者说是Linux的内存管理机制......
卧听檐雨 2013-02-04
  • 打赏
  • 举报
回复
引用 28 楼 stereoMatching 的回复:
我也不知道发生了什么事情...可能是QHash用pool管理resource 所以resource暂时没有被释放? 我用的版本是Qt4.8.4,win764bits, mingw4.6.2 到这里去问问题吧,说不定是Qt4.8.1的bug? http://qt-project.org/forums/ 确定是bug而且Qt4.8.4也有一样的问题后可以到这里报告 https:……
竟然是英文的Form,这个,英文水平有限啊,看看还可以,说就............
stereoMatching 2013-02-04
  • 打赏
  • 举报
回复
其实if(1)没必要,++iter效率比较高
stereoMatching 2013-02-04
  • 打赏
  • 举报
回复
我也不知道发生了什么事情...可能是QHash用pool管理resource 所以resource暂时没有被释放? 我用的版本是Qt4.8.4,win764bits, mingw4.6.2 到这里去问问题吧,说不定是Qt4.8.1的bug? http://qt-project.org/forums/ 确定是bug而且Qt4.8.4也有一样的问题后可以到这里报告 https://bugreports.qt-project.org/secure/IssueNavigator.jspa?pager/start=50
卧听檐雨 2013-02-04
  • 打赏
  • 举报
回复
测试代码如下:
if(1)
{
QHash<QString,QHash<QString,QHash<QString,QString> > > Options;
for(int i=0;i<10;i++)
{
QHash<QString,QHash<QString,QString> > Tmp2;

for(int m=0;m<1000;m++)
{
QHash<QString,QString> Tmp1;
Tmp1.insert(QString::number(m),QString::number(m));
Tmp2.insert(QString::number(m),Tmp1);
}
Options.insert(QString::number(i),Tmp2);
}
}
return App.exec();


请您看,这是刚开始执行的时候,内存大小以及i值;

这是执行到中间的时候,内存大小,i值为9

这是最后的时刻,内存依然在5.7M没有变化,也没有释放....
卧听檐雨 2013-02-04
  • 打赏
  • 举报
回复
引用 25 楼 stereoMatching 的回复:
引用 23 楼 ydpro 的回复:引用 21 楼 stereoMatching 的回复:至于Qt的memory release机制,是基于parent and children的手法 1 : 你的father,children都是QObject 2 : 你的children必须成为father的children 这样一来,father在死亡的时候,就会把……
有关于这几个问题, 1.ReleaseResource这里,我确认都被正确调用了; 2.那个例子,就是QHash嵌套的例子,没有这些方法,只是简单的利用QHash,在我这里的试验确实是不释放内存,这个不牵涉我自定义的数据结构,我用的4.8.1的库,Qt Creator 2.4.1,UBuntu 12.04LTS版本,是不是我的环境配置有问题呢?
stereoMatching 2013-02-04
  • 打赏
  • 举报
回复
引用 23 楼 ydpro 的回复:
引用 21 楼 stereoMatching 的回复:至于Qt的memory release机制,是基于parent and children的手法 1 : 你的father,children都是QObject 2 : 你的children必须成为father的children 这样一来,father在死亡的时候,就会把地下的children都杀光 ……
引用
难道要显式的去调用~QHash()么
不用,你的destructor也不必那么做,直接呼叫delete就好 我测过了,离开scope后memory确实有变小(debug版本) QHash具体如何处理记忆体的我也不清楚,不排除底层用了pool来管理memory的可能性 你某个地方忘了呼叫ReleaseResource? 如果是这个问题,老答案,smart pointer 例如你前面提的scopedPointer,靠人工释放,要找出 哪里忘了释放resource是一件苦差事,请快点搞懂他吧 此外,QString是采用了implicity sharing的 这代表只要有一个"兄弟"还存在,QString的资源就不会被释放 而且QHash也一样是implicit sharing的 implicit sharing http://doc.qt.digia.com/stable/implicit-sharing.html
卧听檐雨 2013-02-04
  • 打赏
  • 举报
回复
引用 19 楼 dext 的回复:
如果实在搞不明白,就 坚持使用 new delete 配对的原则。 继承自 QObject 的类 会在 delete 的时候 通知 相应的容器类。所以不明白的话,就完全手动new delete。 你的例子中,每个Hash 中的 Settings* 没有被释放过吧。
恩,版主大大,这个确实没有被显式的在析构函数中释放过,因为在8楼还有代码贴的是手工释放的...
卧听檐雨 2013-02-04
  • 打赏
  • 举报
回复
引用 21 楼 stereoMatching 的回复:
至于Qt的memory release机制,是基于parent and children的手法 1 : 你的father,children都是QObject 2 : 你的children必须成为father的children 这样一来,father在死亡的时候,就会把地下的children都杀光 你可以把他想像成资料结构的tree 最上层的node……
您说的QT的Parent-Children机制,我看过,也试验过,请您建立一个小工程,在Main.cpp里粘贴这些代码,并执行, if(1) { QHash<QString,QHash<QString,QHash<QString,QString> > > Options; for(int i=0;i<10;i++) { QHash<QString,QHash<QString,QString> > Tmp2; for(int m=0;m<1000;m++) { QHash<QString,QString> Tmp1; Tmp1.insert(QString::number(m),QString::number(m)); Tmp2.insert(QString::number(m),Tmp1); } Options.insert(QString::number(i),Tmp2); } 这些代码只是利用了最基本的QHash类,将其分配到栈上,在其生命周期内,也就是{}之内,他应该是存在的,并进行内存分配的,在{}之外,其生命周期应该结束,进行释放以及回收,这些不都是QT的工作吗,如果QT不能进行自动调用QHash的析构,还请您告诉我怎么释放才能释放掉QHash?难道要显式的去调用~QHash()么?求解惑!~~~
加载更多回复(20)

16,173

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧