当前位置:编程学习 > wap >>

linux Qt 内存泄露 写文件

写xml文件时,怀疑有内存泄露,具体哪泄露没有找出来,附一段代码,希望有哪位大神给解决一下:其中XMLSTR 比较大 最大估计得到100多K 再就是Out这个类型 应该是Qtextstream类 能不能被释放掉bool XMLOp::WriteSetTableEx(SetTable *SetTables,QString FilePath,QString Xml)
{
    int i,j,k;
    QString *XmlStr;
    XmlStr=new QString();

    QHash<QString, Settings*>::const_iterator Cite;
    QHash<QString,SettingOptions*>::const_iterator Site;
    QHash<QString,QString>::const_iterator Oite;

      Cite=SetTables->GetIterator();
    *XmlStr="<Root>\n";
    for(i=0;i<SetTables->Count();i++)
    {
               Settings *TmpSettings;
        QString TmpKey;
        TmpKey=Cite.key();
        *XmlStr+="    <ClassName>";
        *XmlStr +=TmpKey.trimmed()+"\n";
        TmpSettings=Cite.value();
        Site=TmpSettings->GetIterator();
        for(j=0;j<TmpSettings->Count();j++)
        {
            QString SKey;
            SettingOptions *SSettingOptions;

            SKey=Site.key();
            * XmlStr+="        <ConfigData>";
            *XmlStr +=SKey.trimmed()+"\n";
            SSettingOptions=Site.value();
                     Oite=SSettingOptions->GetIterator();
            for(k=0;k<SSettingOptions->Count();k++)
            {
                QString TKey;
                QString Unit;
                TKey=Oite.key();
                *XmlStr+="           <Name>";
                *XmlStr+=TKey.trimmed();
                *XmlStr+="</Name>\n";
                Unit=Oite.value();
                *XmlStr+="           <Value>";
                * XmlStr+=Unit.trimmed();
                *XmlStr+="</Value>\n";
                Oite++;
            }
            *XmlStr+="       </ConfigData>\n";
            Site++;

        }
        *XmlStr+="    </ClassName>\n";
        Cite++;

    }
    *XmlStr+=Xml+"\n";
    *XmlStr+="</Root>";

    //add file operation here
    if(QFile::exists(FilePath))
    {
        QFile::remove(FilePath);
    }
    //Log.Log("开始写入配置文件!\r");
    QFile *file;
    file=new QFile();
     file->setFileName(FilePath);
    if(!file->open(QIODevice::WriteOnly | QIODevice::Truncate) )    return false ;
    QTextStream out(file);
    int XmlCount;
    XmlCount=0;

    out<<*XmlStr;
    file->flush();
    file->close();
    XmlStr->clear();
    delete XmlStr;
    XmlStr=NULL;
    delete file;
    return true;
} --------------------编程问答-------------------- 只是一个函数内的QString没必要new吧,(QString *XmlStr;  XmlStr=new QString();)
还有QFile也没有必要new吧。直接在栈上面声明变量不是很方便吗,函数结束自动销毁,回收内存。

比如:  if(!file->open(QIODevice::WriteOnly | QIODevice::Truncate) )    return false ;
这一行代码,如果失败 return false,前面new 的QString、QFile全部没有释放,内存泄漏了。 --------------------编程问答--------------------
引用 1 楼 jdwx1 的回复:
只是一个函数内的QString没必要new吧,(QString *XmlStr;  XmlStr=new QString();)
还有QFile也没有必要new吧。直接在栈上面声明变量不是很方便吗,函数结束自动销毁,回收内存。

比如:  if(!file->open(QIODevice::WriteOnly | QIODevice::Truncate) )    ……

+1 没必要的就不要new和delete了,一般我用C++的代码风格是一个函数只有一个返回点,就是函数的最后1行的return,像你这种多个return的风格就容易出现这种问题了,当然在有垃圾回收机制的语言里,多个返回点也是被推荐的,有时候良好的代码风格可以帮助你避免不少问题。 --------------------编程问答-------------------- 同问~~
1.是不是QT本身对Hash数据结构的访问机制存在问题呢,使用这种ITL迭代的方式进行访问,是否本身就可能是内存泄露?
2.在排除内存泄露的时候,是否需要对QT库怀疑,现在始终感觉QT的某些机制上是存在问题的,比如QTimer等
恭候大神出现哈~!
--------------------编程问答--------------------
引用 3 楼 ydpro 的回复:
同问~~
1.是不是QT本身对Hash数据结构的访问机制存在问题呢,使用这种ITL迭代的方式进行访问,是否本身就可能是内存泄露?
2.在排除内存泄露的时候,是否需要对QT库怀疑,现在始终感觉QT的某些机制上是存在问题的,比如QTimer等
恭候大神出现哈~!


能说得具体点,探讨下? --------------------编程问答--------------------
引用 4 楼 freebendy 的回复:
引用 3 楼 ydpro 的回复:同问~~
1.是不是QT本身对Hash数据结构的访问机制存在问题呢,使用这种ITL迭代的方式进行访问,是否本身就可能是内存泄露?
2.在排除内存泄露的时候,是否需要对QT库怀疑,现在始终感觉QT的某些机制上是存在问题的,比如QTimer等
恭候大神出现哈~!

能说得具体点,探讨下?

原来在写一个代码的时候,代码如下:
 //    mMutex.lock();
    QHash<QString,DataPoolUnit>::iterator i;
    float Sum;
    Sum=0;
    i=Datas->begin();
       //    DataPoolUnit Unit;
    while(i!=Datas->end())
    {
        //        Unit=i.value();
        if(i.value().ParaType==ParaType)
        {
            Sum+=i.value().ParaValue.toFloat();
        }
        i++;
    }
    //    mMutex.unlock();
    return Sum;
如果不用上面的方式,而是用    DataPoolUnit Unit; 来获取某个值的时候,就会出现泄漏,但是
DataPoolUnit 我是做好了COPY STRUCTURE和析构的 --------------------编程问答--------------------
引用 5 楼 ydpro 的回复:
引用 4 楼 freebendy 的回复:引用 3 楼 ydpro 的回复:同问~~
1.是不是QT本身对Hash数据结构的访问机制存在问题呢,使用这种ITL迭代的方式进行访问,是否本身就可能是内存泄露?
2.在排除内存泄露的时候,是否需要对QT库怀疑,现在始终感觉QT的某些机制上是存在问题的,比如QTimer等
恭候大神出现哈~!

能说得具体点,探讨下?
……

你上面的代码2种用法都不存在内存泄漏,没有看出有资源分配的地方,我觉得要是有泄漏的现象,最好还是检查DataPoolUnit的实现
--------------------编程问答--------------------
引用 6 楼 freebendy 的回复:
引用 5 楼 ydpro 的回复:引用 4 楼 freebendy 的回复:引用 3 楼 ydpro 的回复:同问~~
1.是不是QT本身对Hash数据结构的访问机制存在问题呢,使用这种ITL迭代的方式进行访问,是否本身就可能是内存泄露?
2.在排除内存泄露的时候,是否需要对QT库怀疑,现在始终感觉QT的某些机制上是存在问题的,比如QTimer等
恭候大神出现哈~!……

DatapoolUnit的实现应该没问题,这个可以确认的,我把代码也贴出来,
#include "datapoolunit.h"

DataPoolUnit::DataPoolUnit()
{
    this->PLCMD200Data=new QByteArray;
    this->PLCMM50Data=new QByteArray;
    this->PLCSData=new QByteArray;
    this->WarnFlag=0;
    this->IsWarnEnable=0;
    this->FunctionStatusCode="NA";
    this->NameCode="NA";
    this->DIFlag="2";
    this->Flag="CSD";
    this->WarnCount=0;
}
DataPoolUnit::DataPoolUnit(const DataPoolUnit &d)
{
    *this=d;
}
DataPoolUnit& DataPoolUnit::operator =(const  DataPoolUnit &d)
{
    if(this==&d)
    {
        return*this;
    }
    else
    {
        if(this->Flag=="CSD")
        {
            delete this->PLCSData;
            delete this->PLCMM50Data;
            delete this->PLCMD200Data;
            PLCSData=NULL;
            PLCMM50Data=NULL;
            PLCMD200Data=NULL;
        }
        this->PLCMD200Data=new QByteArray;
        this->PLCMM50Data=new QByteArray;
        this->PLCSData=new QByteArray;
        this->EquipID=d.EquipID;
        this->IsWarnEnable=d.IsWarnEnable;
        this->LastDateTime=d.LastDateTime;
        this->LastValue=d.LastValue;
        this->NameCode=d.NameCode;
        this->ParaClass=d.ParaClass;
        this->FunctionStatusCode=d.FunctionStatusCode;
        this->ParaID=d.ParaID;
        this->ParaName=d.ParaName;
        this->ParaType=d.ParaType;
        this->ParaValue=d.ParaValue;
        * this->PLCMD200Data=*d.PLCMD200Data;
        *this->PLCMM50Data=*d.PLCMM50Data;
        *this->PLCSData=*d.PLCSData;
        this->UpdateTime=d.UpdateTime;
        this->WarnFlag=d.WarnFlag;
        this->DIFlag=d.DIFlag;
        this->WarnCount=d.WarnCount;
        return* this;
    }
}

DataPoolUnit::~DataPoolUnit()
{
    delete this->PLCSData;
    delete this->PLCMM50Data;
    delete this->PLCMD200Data;
    PLCSData=NULL;
    PLCMM50Data=NULL;
    PLCMD200Data=NULL;

} --------------------编程问答--------------------
引用 7 楼 ydpro 的回复:
引用 6 楼 freebendy 的回复:引用 5 楼 ydpro 的回复:引用 4 楼 freebendy 的回复:引用 3 楼 ydpro 的回复:同问~~
1.是不是QT本身对Hash数据结构的访问机制存在问题呢,使用这种ITL迭代的方式进行访问,是否本身就可能是内存泄露?
2.在排除内存泄露的时候,是否需要对QT库怀疑,现在始终感觉QT的某些机制上是存在问题的……


你的实现是有问题的,c++中要记住copy constructor不要调用assign operator, 如果他们有可以复用的代码,请剥离一个函数来实现复用。

copy constructor对同一对象只会被调用一次,被调用的时候对象还没有创建;而assign operator是在对象已经存在的情况下调用的,可以多次调用.

你的赋值操作赋的else分支里面,delete一个没有创建的对象的成员,结果应该是未定义的。

另外,建议在构造函数中,优先使用初始化列表,而不是在函数内进行赋值 --------------------编程问答-------------------- 可以参考:
http://stackoverflow.com/questions/2639017/calling-assignment-operator-in-copy-constructor
http://stackoverflow.com/questions/2639017/calling-assignment-operator-in-copy-constructor --------------------编程问答-------------------- http://stackoverflow.com/questions/1533725/is-it-bad-form-to-call-the-default-assignment-operator-from-the-copy-constructor --------------------编程问答--------------------
引用 8 楼 freebendy 的回复:
引用 7 楼 ydpro 的回复:引用 6 楼 freebendy 的回复:引用 5 楼 ydpro 的回复:引用 4 楼 freebendy 的回复:引用 3 楼 ydpro 的回复:同问~~
1.是不是QT本身对Hash数据结构的访问机制存在问题呢,使用这种ITL迭代的方式进行访问,是否本身就可能是内存泄露?
2.在排除内存泄露的时候,是否需要对QT库怀疑,现在始……

对于您说的意思,我的理解如下:
1.对于copy构造来说,被copy的对象本身是存在的,而copy出的对象是被创建的,所以不能用等号?但是很多时候,都是用等号来进行copy构造的?
2.如果不用等号,应该用什么方式来进行呢,一个单独的函数吗?
3.那个else分支里的,有个Flag,那个Flag就是用来标识1这种情况的,是否被构造过;
如有不对之处,还请指正~! --------------------编程问答--------------------
引用 11 楼 ydpro 的回复:
引用 8 楼 freebendy 的回复:引用 7 楼 ydpro 的回复:引用 6 楼 freebendy 的回复:引用 5 楼 ydpro 的回复:引用 4 楼 freebendy 的回复:引用 3 楼 ydpro 的回复:同问~~
1.是不是QT本身对Hash数据结构的访问机制存在问题呢,使用这种ITL迭代的方式进行访问,是否本身就可能是内存泄露?
2.在排除内……

另外,能不能写个具体示例学习下,还有请看看1楼的代码有问题吗? --------------------编程问答--------------------
引用 11 楼 ydpro 的回复:
引用 8 楼 freebendy 的回复:引用 7 楼 ydpro 的回复:引用 6 楼 freebendy 的回复:引用 5 楼 ydpro 的回复:引用 4 楼 freebendy 的回复:引用 3 楼 ydpro 的回复:同问~~
1.是不是QT本身对Hash数据结构的访问机制存在问题呢,使用这种ITL迭代的方式进行访问,是否本身就可能是内存泄露?
2.在排除内……

对于1和2:

A a;
A a1 = a; // Copy ctor, not assignment operator
A a2;
a2 = a; // Assignment operator

对于3:
这个flag是不需要的,你在一个已经构建了得对象内部判断这个对象有没有被构造,这本身就是个问题。你正确的实现方式应该是,定义一个init函数,将copy ctor和 assignment operator重复的代码放在里面,然后被这两者调用。
--------------------编程问答--------------------
引用 13 楼 freebendy 的回复:
引用 11 楼 ydpro 的回复:引用 8 楼 freebendy 的回复:引用 7 楼 ydpro 的回复:引用 6 楼 freebendy 的回复:引用 5 楼 ydpro 的回复:引用 4 楼 freebendy 的回复:引用 3 楼 ydpro 的回复:同问~~
1.是不是QT本身对Hash数据结构的访问机制存在问题呢,使用这种ITL迭代的方式进行访问,是否本……

本人新手,尚请见谅,还得继续麻烦您,主要是还是有点不理解,呵呵,还请指教,这个代码:
A a;
A a1 = a; // Copy ctor, not assignment operator
您的意思就是说,虽然是=,但是实际上调用的是copy constructor,而不是重载的=操作符?

针对于3,这个对象本身被构建了,但是不是仍然可能进行等号赋值操作呢,如果进行了等号赋值,那么这个不属于copy构造的范畴,那么应该只是重载等号,进行操作,是这样理解吗?如果本身被构建了,那么进行重载赋值的时候,是不是考虑要释放资源呢,不然是否还是会内存泄露~
--------------------编程问答-------------------- @freebendy
方便的话,是否可以加一下qq~ --------------------编程问答--------------------
引用 14 楼 ydpro 的回复:
引用 13 楼 freebendy 的回复:引用 11 楼 ydpro 的回复:引用 8 楼 freebendy 的回复:引用 7 楼 ydpro 的回复:引用 6 楼 freebendy 的回复:引用 5 楼 ydpro 的回复:引用 4 楼 freebendy 的回复:引用 3 楼 ydpro 的回复:同问~~
1.是不是QT本身对Hash数据结构的访问机制存在问题……


=只是一个符号,实际上调用copy ctor还是assignment operator是由编译器决定,我们的代码比较保证在这些情况下都没有问题,不能设置一些假想,对于3,如果你不让copy ctor调用assignment operator,这个flag就是不需要的,因为在赋值的时候你必须释放已分配的资源。 --------------------编程问答--------------------
引用 15 楼 ydpro 的回复:
@freebendy
方便的话,是否可以加一下qq~

私信你了,上班时间qq和mail都上不了的,只能上网 --------------------编程问答--------------------
引用 17 楼 freebendy 的回复:
引用 15 楼 ydpro 的回复:@freebendy
方便的话,是否可以加一下qq~
私信你了,上班时间qq和mail都上不了的,只能上网

1.ok,已经加了您的qq
2.那么这样我的copy构造就需要重新写了,实际上对于=这种做法我也发现了对于已经构建的对象是有问题的,所以才会加标志位,这样一说 我就更清楚了,这样我改下试试看
3.还请您麻烦看看下面的代码,为什么会造成泄漏
//曲线数据存储,一天一个文件,300个节点
//1.判断文件是否存在
//2.如果文件不存在,则新建,并将XML字符串直接写入文件,形成SETTABLE类可识别的格式
//3.如果文件存在,则利用SETTABLE将其读入内存,然后利用方法将其生成XML字符串,将本次需要
//追加的内容加载到字符串后,然后重新写入XML文件,释放临时资源
void SaveHisData::DataGraphicSaveEx(QString mCurtTime,int GraphicNo)
{
    //首先判断 xml文件是否存在
    //根据当前日期,生成文件名

    QDateTime CTime;
    QString DirName;
    QString FileName;
    CTime=QDateTime::fromString(mCurtTime,"yyyy-MM-dd HH:mm:ss");
    DirName=CTime.toString("yyyyMMdd");
    DirName="/media/mmcblk0p1/Graphic/"+DirName; //在相应的文件夹下建立 文件夹
    QDir temp ; //判断文件夹是否存在
    if (!(temp.exists(DirName)))
    {
        temp.mkdir(DirName); //创建文件夹
    }
    //--------------------创建文件
    FileName="Graphic";  //文件的名称为  G1  G2   ... G300

    QString FilePath;
    FilePath=DirName+"/"+FileName+".xml";

    QFile File;
    //    File=new QFile();
    if (!File.exists(FilePath)) //如果文件不存在
    {
        //如果不存在,就先创建一个文件
        File.setFileName(FilePath);
        //对文件的操作----------写数据
        if (File.open(QIODevice::WriteOnly | QIODevice::Append))
        {
            QTextStream out(&File);
            QString XmlStr;

            XmlStr+="<Root>\n";
            XmlStr+="  <ClassName>";
            XmlStr+= QString::number(GraphicNo)+"\n";  //格式: 1

            //压力的数据 //参数ID固定为 ExtPLCSumPa
            QString YLSum;
            YLSum=QString::number(this->mDataPool->GetSumValueByParaType("压力"),'f',2);
            XmlStr+="    <ConfigData>";
            XmlStr+="ExtPLCSumPa\n";
            XmlStr+="      <Name>设备ID</Name>\n";
            XmlStr+="      <Value></Value>\n";
            XmlStr+="      <Name>参数ID</Name>\n";
            XmlStr+="      <Value>ExtPLCSumPa</Value>\n";
            XmlStr+="      <Name>参数值</Name>\n";
            XmlStr+="      <Value>"+YLSum.trimmed()+"</Value>\n";
            XmlStr+="      <Name>更新时间</Name>\n";
            XmlStr+="      <Value>"+CTime.toString("yyyy-MM-dd HH:mm:ss")+"</Value>\n";
            XmlStr+="      <Name>参数名称</Name>\n";
            XmlStr+="      <Value>总压力</Value>\n";
            XmlStr+="      <Name>参数类型</Name>\n";
            XmlStr+="      <Value>总压力</Value>\n";
            XmlStr+="    </ConfigData>\n";

            //获取总瞬时流量 //参数ID固定为 FlowSumE
            QString SSLLSum;
            SSLLSum=QString::number(this->mDataPool->GetSumValueByParaType("瞬时流量"),'f',2);
            XmlStr+="    <ConfigData>";
            XmlStr+="FlowSumE\n";
            XmlStr+="      <Name>设备ID</Name>\n";
            XmlStr+="      <Value></Value>\n";
            XmlStr+="      <Name>参数ID</Name>\n";
            XmlStr+="      <Value>FlowSumE</Value>\n";
            XmlStr+="      <Name>参数值</Name>\n";
            XmlStr+="      <Value>"+SSLLSum.trimmed()+"</Value>\n";
            XmlStr+="      <Name>更新时间</Name>\n";
            XmlStr+="      <Value>"+CTime.toString("yyyy-MM-dd HH:mm:ss")+"</Value>\n";
            XmlStr+="      <Name>参数名称</Name>\n";
            XmlStr+="      <Value>总瞬时流量</Value>\n";
            XmlStr+="      <Name>参数类型</Name>\n";
            XmlStr+="      <Value>总瞬时流量</Value>\n";
            XmlStr+="    </ConfigData>\n";

            XmlStr+="  </ClassName>\n";
            XmlStr+="</Root>\n";


            out<<XmlStr;
            XmlStr.clear();
        }

        File.flush();
        File.close();
    }
    else//如果文件存在
    {
        SetTable Tmp;
        this->Xop->CreateSetTableByXml(FilePath,&Tmp);
        QString XmlStr;
        XmlStr+="  <ClassName>";
        XmlStr+= QString::number(GraphicNo)+"\n";  //格式: 1
        //压力的数据 //参数ID固定为 ExtPLCSumPa
        QString YLSum;
        YLSum=QString::number(this->mDataPool->GetSumValueByParaType("压力"),'f',2);
        XmlStr+="    <ConfigData>";
        XmlStr+="ExtPLCSumPa\n";
        XmlStr+="      <Name>设备ID</Name>\n";
        XmlStr+="      <Value></Value>\n";
        XmlStr+="      <Name>参数ID</Name>\n";
        XmlStr+="      <Value>ExtPLCSumPa</Value>\n";
        XmlStr+="      <Name>参数值</Name>\n";
        XmlStr+="      <Value>"+YLSum.trimmed()+"</Value>\n";
        XmlStr+="      <Name>更新时间</Name>\n";
        XmlStr+="      <Value>"+CTime.toString("yyyy-MM-dd HH:mm:ss")+"</Value>\n";
        XmlStr+="      <Name>参数名称</Name>\n";
        XmlStr+="      <Value>总压力</Value>\n";
        XmlStr+="      <Name>参数类型</Name>\n";
        XmlStr+="      <Value>总压力</Value>\n";
        XmlStr+="    </ConfigData>\n";

        //获取总瞬时流量 //参数ID固定为 FlowSumE
        QString SSLLSum;
        SSLLSum=QString::number(this->mDataPool->GetSumValueByParaType("瞬时流量"),'f',2);
        XmlStr+="    <ConfigData>";
        XmlStr+="FlowSumE\n";
        XmlStr+="      <Name>设备ID</Name>\n";
        XmlStr+="      <Value></Value>\n";
        XmlStr+="      <Name>参数ID</Name>\n";
        XmlStr+="      <Value>FlowSumE</Value>\n";
        XmlStr+="      <Name>参数值</Name>\n";
        XmlStr+="      <Value>"+SSLLSum.trimmed()+"</Value>\n";
        XmlStr+="      <Name>更新时间</Name>\n";
        XmlStr+="      <Value>"+CTime.toString("yyyy-MM-dd HH:mm:ss")+"</Value>\n";
        XmlStr+="      <Name>参数名称</Name>\n";
        XmlStr+="      <Value>总瞬时流量</Value>\n";
        XmlStr+="      <Name>参数类型</Name>\n";
        XmlStr+="      <Value>总瞬时流量</Value>\n";
        XmlStr+="    </ConfigData>\n";
        XmlStr+="  </ClassName>\n";
        this->Xop->WriteSetTableEx(&Tmp,FilePath,XmlStr);
        Tmp.ReleaseResource();
   
    }
   
} --------------------编程问答-------------------- 另,改写了DatapoolUnit的实现,请您看下,十分感谢!!!!
#include "datapoolunit.h"

DataPoolUnit::DataPoolUnit()
{
    this->PLCMD200Data=new QByteArray;
    this->PLCMM50Data=new QByteArray;
    this->PLCSData=new QByteArray;
    this->WarnFlag=0;
    this->IsWarnEnable=0;
    this->FunctionStatusCode="NA";
    this->NameCode="NA";
    this->DIFlag="2";
    this->Flag="CSD";
    this->WarnCount=0;
}

DataPoolUnit::DataPoolUnit(const DataPoolUnit &d)
{
    this->PLCMD200Data=new QByteArray;
    this->PLCMM50Data=new QByteArray;
    this->PLCSData=new QByteArray;
    this->EquipID=d.EquipID;
    this->IsWarnEnable=d.IsWarnEnable;
    this->LastDateTime=d.LastDateTime;
    this->LastValue=d.LastValue;
    this->NameCode=d.NameCode;
    this->ParaClass=d.ParaClass;
    this->FunctionStatusCode=d.FunctionStatusCode;
    this->ParaID=d.ParaID;
    this->ParaName=d.ParaName;
    this->ParaType=d.ParaType;
    this->ParaValue=d.ParaValue;
    * this->PLCMD200Data=*d.PLCMD200Data;
    *this->PLCMM50Data=*d.PLCMM50Data;
    *this->PLCSData=*d.PLCSData;
    this->UpdateTime=d.UpdateTime;
    this->WarnFlag=d.WarnFlag;
    this->DIFlag=d.DIFlag;
    this->WarnCount=d.WarnCount;
}
DataPoolUnit& DataPoolUnit::operator =(const  DataPoolUnit &d)
{
    if(this==&d)
    {
        return*this;
    }
    else
    {
        this->EquipID=d.EquipID;
        this->IsWarnEnable=d.IsWarnEnable;
        this->LastDateTime=d.LastDateTime;
        this->LastValue=d.LastValue;
        this->NameCode=d.NameCode;
        this->ParaClass=d.ParaClass;
        this->FunctionStatusCode=d.FunctionStatusCode;
        this->ParaID=d.ParaID;
        this->ParaName=d.ParaName;
        this->ParaType=d.ParaType;
        this->ParaValue=d.ParaValue;
        * this->PLCMD200Data=*d.PLCMD200Data;
        *this->PLCMM50Data=*d.PLCMM50Data;
        *this->PLCSData=*d.PLCSData;
        this->UpdateTime=d.UpdateTime;
        this->WarnFlag=d.WarnFlag;
        this->DIFlag=d.DIFlag;
        this->WarnCount=d.WarnCount;
        return *this;
    }
}

DataPoolUnit::~DataPoolUnit()
{
    delete this->PLCSData;
    delete this->PLCMM50Data;
    delete this->PLCMD200Data;
    PLCSData=NULL;
    PLCMM50Data=NULL;
    PLCMD200Data=NULL;

}
--------------------编程问答--------------------
引用 18 楼 ydpro 的回复:
引用 17 楼 freebendy 的回复:引用 15 楼 ydpro 的回复:@freebendy
方便的话,是否可以加一下qq~
私信你了,上班时间qq和mail都上不了的,只能上网
1.ok,已经加了您的qq
2.那么这样我的copy构造就需要重新写了,实际上对于=这种做法我也发现了对于已经构建的对象是有问题的,所以才会加标志位,这样一说 我就更清楚了,这样……



你这函数也太长了吧?memory leak没注意看出来,其他问题倒不少:
1.代码c风格, 遵循RAII,变量的声明和初始化写到一起吧,
2. if (!File.exists(FilePath)) //如果文件不存在 ---QFile有这个代参数的方法?
3. 组装字符串就抽离出去吧,跟程序逻辑混合在一起,降低代码可读性。

养成良好的编码风格很重要,可以避免很多的低级错误。 --------------------编程问答-------------------- 另外,别再在别人的地盘继续下去了 --------------------编程问答--------------------
引用 20 楼 freebendy 的回复:
引用 18 楼 ydpro 的回复:引用 17 楼 freebendy 的回复:引用 15 楼 ydpro 的回复:@freebendy
方便的话,是否可以加一下qq~
私信你了,上班时间qq和mail都上不了的,只能上网
1.ok,已经加了您的qq
2.那么这样我的copy构造就需要重新写了,实际上对于=这种做法我也发现了对于已经构建的对象是有问题的,所以才会加……

恩,代码是比较长,主要是XML字符串组装的过程,其实逻辑很简单,Qfile是有这个方法的 --------------------编程问答--------------------
引用 21 楼 freebendy 的回复:
另外,别再在别人的地盘继续下去了

热烈欢迎在此讨论问题,大神就是大神。。。。解惑啊!!!! --------------------编程问答--------------------
引用 21 楼 freebendy 的回复:
另外,别再在别人的地盘继续下去了


没事的,我想楼主也是欢迎我们讨论的,其实楼主就是我同事,哈哈 --------------------编程问答-------------------- 大神还在吗,还等着解惑呢....真心求教啊...... --------------------编程问答--------------------
引用 19 楼 ydpro 的回复:
另,改写了DatapoolUnit的实现,请您看下,十分感谢!!!!
#include "datapoolunit.h"

DataPoolUnit::DataPoolUnit()
{
    this->PLCMD200Data=new QByteArray;
    this->PLCMM50Data=new QByteArray;
    this->……


问题还是有啊
1.DataPoolUnit::DataPoolUnit() 所有成员的初始化都可以放到初始化列表的,这样可以提高效率。
2.同理DataPoolUnit::DataPoolUnit(const DataPoolUnit &d)也可以这样做;此外你的那些QByteArray可以使用它的copy ctor啊,为什么先创建再赋值,很低效。
3.在析构函数,重新赋值为NULL其实是没有必要的,因为对象被析构了,这些指针你也用不了 --------------------编程问答--------------------
引用 26 楼 freebendy 的回复:
引用 19 楼 ydpro 的回复:另,改写了DatapoolUnit的实现,请您看下,十分感谢!!!!
#include "datapoolunit.h"

DataPoolUnit::DataPoolUnit()
{
    this->PLCMD200Data=new QByteArray;
    this->PLCMM50Data=new QByte……

恩,您说的问题,我会再改动下,现在,
1.这样写是不是就是没有问题的呢,不会存在泄漏什么的吧,原理理解上应该没有误差了吧?
2.再就是您说的初始化列表,是不是就是指一个Init函数呢? --------------------编程问答--------------------
引用 27 楼 ydpro 的回复:
引用 26 楼 freebendy 的回复:引用 19 楼 ydpro 的回复:另,改写了DatapoolUnit的实现,请您看下,十分感谢!!!!
#include "datapoolunit.h"

DataPoolUnit::DataPoolUnit()
{
    this->PLCMD200Data=new QByteArray;
    this-……


初始化列表是:

A::A(int a, int b): mA(a), mB(b), mC(NULL)
{
}

--------------------编程问答--------------------
引用 28 楼 freebendy 的回复:
引用 27 楼 ydpro 的回复:引用 26 楼 freebendy 的回复:引用 19 楼 ydpro 的回复:另,改写了DatapoolUnit的实现,请您看下,十分感谢!!!!
#include "datapoolunit.h"

DataPoolUnit::DataPoolUnit()
{
    this->PLCMD200Data=new QByt……

好的,学习了.... --------------------编程问答-------------------- 早上来了,继续来盖楼~哈哈

现在还有个问题,就是两个窗体互相调用的问题,比如需要在窗体A中调用显示窗体B,同时关闭窗体A,应该用什么样的方式比较好呢? --------------------编程问答--------------------
引用 30 楼 ydpro 的回复:
早上来了,继续来盖楼~哈哈

现在还有个问题,就是两个窗体互相调用的问题,比如需要在窗体A中调用显示窗体B,同时关闭窗体A,应该用什么样的方式比较好呢?


所谓的关闭是什么意思?如果只是表面上关闭,可以把窗口隐藏了,也可以由一个父窗口控制AB2个子窗口,主要看你的应用场景考虑 --------------------编程问答--------------------
引用 31 楼 freebendy 的回复:
引用 30 楼 ydpro 的回复:早上来了,继续来盖楼~哈哈

现在还有个问题,就是两个窗体互相调用的问题,比如需要在窗体A中调用显示窗体B,同时关闭窗体A,应该用什么样的方式比较好呢?

所谓的关闭是什么意思?如果只是表面上关闭,可以把窗口隐藏了,也可以由一个父窗口控制AB2个子窗口,主要看你的应用场景考虑

关闭是真正意义的关闭,而不是隐藏~,主要是考虑在嵌入式板子上运行,内存空间有限,那个属性Qt::WA_DeleteOnClose已经设置,想知道如何进行窗体互调,看看自己的写法有没有错误 --------------------编程问答-------------------- 应该没问题吧,你可以测试下看看窗口被销毁了没 --------------------编程问答--------------------
引用 33 楼 freebendy 的回复:
应该没问题吧,你可以测试下看看窗口被销毁了没

测试了,窗口确实被销毁了,但是内存没有降低~ --------------------编程问答--------------------
引用 34 楼 ydpro 的回复:
引用 33 楼 freebendy 的回复:应该没问题吧,你可以测试下看看窗口被销毁了没
测试了,窗口确实被销毁了,但是内存没有降低~


你一个窗口占用内存才多大啊,你要测试就要用占用内存很大的窗口对象的看看内存有没有降低 --------------------编程问答--------------------
引用 35 楼 freebendy 的回复:
引用 34 楼 ydpro 的回复:
引用 33 楼 freebendy 的回复:应该没问题吧,你可以测试下看看窗口被销毁了没
测试了,窗口确实被销毁了,但是内存没有降低~

你一个窗口占用内存才多大啊,你要测试就要用占用内存很大的窗口对象的看看内存有没有降低

就是这么做的,放了好多控件。。。。。 --------------------编程问答--------------------
引用 35 楼 freebendy 的回复:
引用 34 楼 ydpro 的回复:
引用 33 楼 freebendy 的回复:应该没问题吧,你可以测试下看看窗口被销毁了没
测试了,窗口确实被销毁了,但是内存没有降低~

你一个窗口占用内存才多大啊,你要测试就要用占用内存很大的窗口对象的看看内存有没有降低

大神,看看这个问题怎么解决啊?麻烦了,多谢!!
http://bbs.csdn.net/topics/390357552?page=1
补充:移动开发 ,  Qt
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,