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程序运行结果:
数组地址0x28fe700: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,转载请注明出处。
当天才遇上白痴时会发生化学反应吗?答案是肯定的!!!