C++通过ADO连接数据库出现出现访问冲突,请问具体什么原因?


##运行时,出现问题:

histrec.exe 中的 0x7c938fea 处未处理的异常: 0xC0000005: 写入位置 0x00000010 时发生访问冲突。

请问该如何修改?

   
  // histrec.cpp : 定义控制台应用程序的入口点。
  
#include "stdafx.h"
#pragma comment(lib,"ws2_32.lib")


class AnaPoint
{
public:
AnaPoint();
void SetAltId(_bstr_t Str);
void SetEng(float num);
_bstr_t GetAltId();
float GetEng();
private:
_bstr_t AltId;
float Eng;
};


AnaPoint::AnaPoint()
{
AltId = "0";
Eng = 0.0;
}
void AnaPoint::SetAltId(_bstr_t Str)
{
AltId = Str;
}
void AnaPoint::SetEng(float num)
{
Eng = num;
}
float AnaPoint::GetEng()
{
return Eng;
}


_bstr_t AnaPoint::GetAltId()
{
return AltId;
}


int _tmain(int argc, _TCHAR* argv[])
{
//初始化。
::CoInitialize(NULL);
_ConnectionPtr pConn(__uuidof(Connection));
_RecordsetPtr pRst(__uuidof(Recordset));
_CommandPtr pCmd(__uuidof(Command));

//连接数据库
pConn->ConnectionString="persist security info=false;data source=MOSAIC_scada";
pConn->Open("","","",adConnectUnspecified);

//查看数据库中有多少点。
_bstr_t AltId_count_sql="select count(AltId) from AnaT where AltId like 'LHS_%'";
pRst=pConn->Execute(AltId_count_sql,NULL,adCmdText);
int Ana_TOTAL = pRst->Fields->GetItem(long(0))->GetValue();
cout<<Ana_TOTAL<<endl;
AnaPoint *LHSAnaPtr= new AnaPoint[Ana_TOTAL];

//获得数据库中的 字段名 “AltId”。
_bstr_t GetAltId_Sql="select AltId from AnaT where AltId like 'LHS_%'";
pRst=pConn->Execute(GetAltId_Sql,NULL,adCmdText);
int j=0;
while(!pRst->adoEOF)
{
_bstr_t str=(_bstr_t)pRst->GetCollect("AltId");
LHSAnaPtr[j].SetAltId(str);
// cout<<LHSAnaPtr[j].GetAltId()<<endl;
j++;
pRst->MoveNext();
}
// cout<<LHSAnaPtr[67].GetAltId()<<endl;



// 根据AltId号 获得实时数据Eng的值。
int k=0;
for (k=0;k<Ana_TOTAL;k++)
{
_bstr_t GetEng_Sql="select Eng from AnaT where AltId ='"+LHSAnaPtr[k].GetAltId()+"'";
try
{
pCmd->put_ActiveConnection(_variant_t((IDispatch*)pConn));
pRst=pConn->Execute(GetEng_Sql,NULL,adCmdText);
//问题出在这里:当循环到k=105时,出现以上图片中的错误。请问这是怎么回事?
}
catch(_com_error e)
{
cout<<e.Description();
}
_variant_t eng=pRst->GetCollect("Eng");
CString str_eng;
float eng_fl=eng.fltVal;
str_eng.Format("%.4f",eng_fl);
LHSAnaPtr[k].SetEng(eng_fl);
cout<<k<<endl;
// cout<<LHSAnaPtr[k].GetAltId()<<endl;
}


//释放 关闭数据库。
pRst->Close();
pConn->Close();
pCmd.Release();
pRst.Release();
pConn.Release();
::CoUninitialize();
return 0;
}

数据库 C++

猫咪阴森森 12 years ago
   
  pRst=pConn->Execute(...);
  
//对数据集进行操作,并没有关闭
pRst=pConn->Execute(...);

出错的原因是数据集pRst在指向之前没有关闭就指向另一个数据集了。。连续两个execute,中间并没有关闭,在这两个之间加上一个pRst->Close();就可以解决问题了(没有亲自测试,原理上来说是这样的,之前碰到过类似情况)。
其实这么写,一般都会奔溃的,即使不崩,也会有内存泄露。不过我之前写的时候是一只崩溃的。
推荐一种比较好的写法,每次在用数据集之前,都判断一下是否已经指向。如果已经指向了,就先关闭一下。这样可以统一,避免程序出现混乱。另外,可以参考CDateBase类的做法,把这些初始化还有释放什么的,自己定义成一个类。模仿成CDateBase类的形式,统一的进行管理。这样可以避免出错。

wss0419 answered 12 years ago

Your Answer