读书人

ado内存泄漏待

发布时间: 2012-02-21 16:26:23 作者: rapoo

ado内存泄漏,在线等待!
程序内存一直增大到90M,就“提示存储空间不足,无法完成此操作”


源代码:

//Read all points recent data value from sql server
int GetDataFromNDE(map<string,double>& TagValues)
{
//CoInitialize(NULL);
if (first)
{
HRESULT hr = pMyConnect.CreateInstance("ADODB.Connection");
hr = pRecordset.CreateInstance("ADODB.Recordset");

first = false;
}

string strConnect = "Provider=SQLOLEDB;Server=" + NDECfg.strServerName +
";database=" + NDECfg.strDBName;

//connect to database
cout << ">> 连接NDE数据库" << endl;
g_Log.AddLine( ">> 连接NDE数据库");

try
{
pMyConnect->Open(strConnect.c_str(), NDECfg.strDBUser.c_str(),
NDECfg.strDBPwd.c_str(), NULL);
}
catch (_com_error& e)
{
CString strLog;
strLog.Format(">> 连接NDE数据库错误:%s", (char*)e.Description());
cout << (LPCTSTR)strLog << endl;
g_Log.AddLine(strLog);
}


//FORMAT: select ID,T*** from LS288Point where DT='****-**-**'

//get table column name
string strColumnName = "T";

if (g_PointSerialNum < 0)
{
g_PointSerialNum += 288;
}
//convert point serial num to string
char pszSerialNum[4];
itoa(g_PointSerialNum, pszSerialNum, 10);
strColumnName += pszSerialNum;
//strColumnName = "T1";


//strcpy(pszCurDate, "2007-11-14");
//construct sql statement
string strSQL ="select ID," + strColumnName +
" from LS288Point where DT='" + g_strPointDate + "'";

//read data
cout << ">> 打开数据表" << endl;
try
{
pRecordset->Open(_variant_t(strSQL.c_str()),
_variant_t((IDispatch*)pMyConnect, true),
adOpenDynamic,
adLockOptimistic,
adCmdText);

}
catch (_com_error& e)
{
CString strLog;
strLog.Format(">> 打开数据表错误:%s", (char*)e.Description());
cout << (LPCTSTR)strLog << endl;
g_Log.AddLine(strLog);
}

cout << ">> 从NDE数据表读取数据" << endl;
g_Log.AddLine(">> 从NDE数据表读取数据");

string strTagName;
double dValue;
map<string, string>::iterator EndIt = NDECfg.mapTagAndDesc.end();

try
{
while (!pRecordset->adoEOF)
{
strTagName = (char*)(_bstr_t)pRecordset->Fields->GetItem("ID")->Value;
dValue = (double)pRecordset->Fields->GetItem(strColumnName.c_str())->Value;

CString strLog;
strLog.Format("%s %f", strTagName.c_str(), dValue);
cout << (LPCTSTR)strLog << endl;
g_Log.AddLine(strLog);

//only record tag values that appeared in NDE.ini
if (NDECfg.mapTagAndDesc.find(strTagName) != EndIt)
{
TagValues[strTagName] = dValue;
}

pRecordset->MoveNext();
}

cout << ">> 断开NDE数据库连接" << endl;
g_Log.AddLine(">> 断开NDE数据库连接");

pRecordset->Close();
pMyConnect->Close();

//pRecordset = NULL;
//pMyConnect = NULL;

//CoUninitialize();
}
catch (_com_error& e)
{
CString strLog;
strLog.Format(">> 读取数据错误:%s", (char*)e.Description());
cout << (LPCTSTR)strLog << endl;
g_Log.AddLine(strLog);
}

return 0;
}

[解决办法]
//pRecordset = NULL;
//pMyConnect = NULL;


这两句不要屏蔽..平时关闭ADO进行下面操作就可以了..:

m_pRs->Close();
m_pConn->Close();
m_pRs=NULL;
m_pConn=NULL;
CoUninitialize();
[解决办法]

m_pRs-> Close();
m_pConn-> Close();
m_pRs.release()
m_pConn.release()
m_pRs=NULL;
m_pConn=NULL;
CoUninitialize();
[解决办法]
智能指针重载了 = 操作符, m_pRs=NULL; 的效果等同 m_pRs.release();

[解决办法]
也要删除

m_pRs=NULL;
m_pConn=NULL;


因为你每次调这个函数,你都会重新去建立连接,所以你要释放

CoUninitialize()
这个可以不调

[解决办法]
你函数一开始就
HRESULT hr = pMyConnect.CreateInstance("ADODB.Connection");
hr = pRecordset.CreateInstance("ADODB.Recordset");
了啊,所以
m_pRs=NULL;
m_pConn=NULL;
是没有问题的..
[解决办法]
要养成良好的有借有还的使用习惯,使用了资源,一定要记得在合适的时机释放资源
[解决办法]
你应该把前面的一下操作放大函数外面,把数据库变量 设置成全局变量就可以了。
这样每次连接 每次断开 速度还不得曼死,内存是不是没有管理好 造成的这个问题

读书人网 >VC/MFC

热点推荐