Qt C++ 指向对象的指针与内存分配的问题分析

20160408 Qt C++ 指向对象的指针与内存分配的问题分析


  首先用new初始化类对象,该对象获得一个内存地址:0x279e588。该对象负责下载一个Url源代码并保存到本地,它需要一定的时间访问互联网,以获取源代码。

  该对象运行结束后,通过(信号槽)运行类成员函数,执行语句delete this,释放内存(因为有信号槽的存在,Qt无法自动释放内存)。

  但是,如果该对象并未运行完成(未delete this),又用new初始化相同名字的对象,就会建立一个新的内存地址:0x27b07e0,该对象被新地址覆盖。

  问题来了,由于原地址0x279e588还在内存中运行,而且我们找不到它了(对象名被新地址覆盖),这可能导致内存溢出!例如说:假设HTTP服务器访问超时,该原地址就会在那里傻傻的等待,永远都不会执行delete this,将导致内存一直被占用,永远不会被释放(除非关闭EXE程序)。当同时下载几千个以上Url源代码,超时问题必然反复出现,最终导致内存溢出报错。


  解决办法:因为不确定对象何时运行结束?何时被释放?又何时出现超时问题?那就不要反复的new重名对象,也不要执行delete this。通过建立指向对象的指针数组,存放若干个并行下载的对象,写一些判断语句去追踪、计时每一个对象,判断下如:

  判断条件一:如果该对象运行结束,不释放内存,继续下载下一个Url地址。

  判断条件二:如果该对象计时超时,不释放内存,重新下载原来的Url地址。

  当且只有所有Url都下载完成,才通过外部命令"delete 对象名"的方式释放内存。


版权所有:曦痕Sieyoo,转载请注明出处。

当天才遇上白痴时会发生化学反应吗?答案是肯定的!!!



分析的源代码如下:


Qt程序运行结果:

数组地址0x28fe70
0:0x279e588   //该对像指针地址负责下载百度源代码,96KB
0:0x27b07e0   //该对像指针地址负责下载新浪源代码,21KB
等5秒,5秒过了!   //给予5秒的下载时间
0:0x27b1440   //该对像指针地址负责下载搜狐源代码,412KB
等5秒,5秒过了!   //给予5秒的下载时间
程序运行结束!
请按任意键继续. . .


Qt程序运行结果:



Qt程序运行后生成的文件:




测试用的Main函数:


using namespace std;
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QTextCodec *codec = QTextCodec::codecForName("GB18030");         //设定默认的程序编码
    QTextCodec::setCodecForLocale(codec);
    QTextCodec::setCodecForCStrings(codec);
    QTextCodec::setCodecForTr(codec);
    int n=6;
    jDownloadHttpCode *zDownloadHttpCode[n];
    cout<<"数组地址"<<zDownloadHttpCode<<endl;
    zDownloadHttpCode[0]=new jDownloadHttpCode("./lalalalalala");
    zDownloadHttpCode[0]->StartDowndoad("http://www.baidu.com","./1.html");
    cout<<"0:"<<zDownloadHttpCode[0]<<endl;
    zDownloadHttpCode[0]=new jDownloadHttpCode("./lalalalalala");
    zDownloadHttpCode[0]->StartDowndoad("http://www.sina.com","./2.html");
    cout<<"0:"<<zDownloadHttpCode[0]<<endl;
    xWaitTime(5);
    zDownloadHttpCode[0]=new jDownloadHttpCode("./lalalalalala");
    cout<<"0:"<<zDownloadHttpCode[0]<<endl;
    zDownloadHttpCode[0]->StartDowndoad("http://www.sohu.com","./3.html");
    xWaitTime(5);//等待5秒的下载时间
    cout<<"程序运行结束!"<<endl;
    system("pause");
}
 

定义一个类jDownloadHttpCode:下载网页源代码。

其过程如下:

1、new,传参下载目录,并做一些初始化;

2、通过类函数::StartDowndoad,执行下载命令,传参要下载的Url地址和源代码保存的位置;

3、建立Qt信号槽,等待信号readyRead,即接收到源代码准备并读取。执行函数::httpReadyRead,将源代码写入文件;

4、建立Qt信号槽,等待信号finished,即类对象程序运行结束。执行函数::httpFinished,用delete this释放占用的内存。

jDownloadHttpCode代码如下:

=========================================================================

#include <jDownloadHttpCode.h>
#include <QString>
#include <iostream>
#include <QtNetwork/QtNetwork>
#include <xOperateDirectory.h>
#include <xOperateString.h>
#include <xOperateFile.h>
using namespace std;
jDownloadHttpCode::jDownloadHttpCode(QString vDirectory)
//----------------------------------------------------------
//下载链接源代码
//传入二个参数:一个链接;指定存放目录。
//对类做声明,当调用类的StartDowndoad成员时开始下载
{
    tDirectory=vDirectory;
    QDir vDir(tDirectory);//如果目录不存在则新建目录
    if(!vDir.exists())
        xCreateDirectory(tDirectory);
}
jDownloadHttpCode::~jDownloadHttpCode()
{
    delete ztQUrl;
    delete ztQFileInfo;
    delete ztQFile;
    delete ztQNetworkReply;
    delete ztQNetworkAccessManager;
}
QString jDownloadHttpCode::StartDowndoad(QString vUrl,QString vFileName)
{
    tUrl=vUrl;
    tFileName=vFileName;
    ztQUrl=new QUrl(tUrl);//这里传入链接的地址
    ztQFileInfo=new QFileInfo(ztQUrl->path());//这里传入链接的地址,所对应的路径信息
    xReCreateFile(tDirectory+tFileName);
    ztQFile=new QFile(tDirectory+tFileName);
    ztQNetworkAccessManager = new QNetworkAccessManager(this);
    if(!ztQFile->open(QIODevice::WriteOnly))
    {   //如果打开文件失败,则删除file,并使file指针为0,然后返回
        cout<<"DownUrl Robot: "<<tFileName.toStdString()<<"file open error!"<<endl;
        delete ztQFile;
        ztQFile = 0;
        return false;
    }
    //链接请求
    ztQNetworkAccessManager = new QNetworkAccessManager(this);
    ztQNetworkReply = ztQNetworkAccessManager->get(QNetworkRequest(*ztQUrl));
    //下面关联信号和槽
    connect(ztQNetworkReply,SIGNAL(readyRead()),this,SLOT(httpReadyRead()));
    //下载完成后
    connect(ztQNetworkReply,SIGNAL(finished()),this,SLOT(httpFinished()));
    return tFileName;
}
void jDownloadHttpCode::httpReadyRead()
{
    if (ztQFile) ztQFile->write(ztQNetworkReply->readAll());  //如果文件存在,则写入文件
    else cout<<"找不到文件,无法向文件写入源代码"<<endl;
}
void jDownloadHttpCode::httpFinished()
{
    ztQFile->flush();
    ztQFile->close();
    ztQNetworkReply->deleteLater();
    ztQNetworkReply = 0;
    delete ztQFile;
    ztQFile = 0;
    delete this;
}
 

=========================================================================


版权所有:曦痕Sieyoo,转载请注明出处。

当天才遇上白痴时会发生化学反应吗?答案是肯定的!!!


  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值