ADO连接数据库Debug调试报:Run-Time Check Failure

jamseyang 2014-11-03 02:12:40
ADO方式连接Oracle数据库,Test函数执行return后崩溃,debug调试时报以下错误:
Run-Time Check Failure #2 - Stack around the variable 'szSql' was corrupted.
但是在release下运行正常,请问这是怎么回事,哪里出问题了?

bool Test()
{
char szSql[64] = "select * from TEST";
int iRows = 0;
char szError[512] = {0};
char szID[128] = {0};
char szName[128] = {0};
char szAddress[128] = {0};

try
{
_RecordsetPtr pRecord = m_conPtr->Execute((_bstr_t)szSql,(VARIANT*)&iRows,adCmdText);
strcpy(szID, (char*)(_bstr_t)pRecord->GetCollect("ID"));
strcpy(szName, (char*)(_bstr_t)pRecord->GetCollect("Name"));
strcpy(szAddress, (char*)(_bstr_t)pRecord->GetCollect("Address"));
pRecord->Close();

}
catch(_com_error e)
{
printf("%s\n", e.ErrorMessage())
exit(-1);
}

return true;
}


付报错截图:
...全文
272 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
jamseyang 2014-11-05
  • 打赏
  • 举报
回复
这就是问题所在,第二个参数填NULL或VARIANT指针类型后,Debug不再报错,感谢大家的耐心指教!
引用 15 楼 zyq5945 的回复:
int iRows; m_conPtr->Execute((_bstr_t)szSql,(VARIANT*)&iRows,adCmdText); 肯定是不能这样强制转换的,两个数据类型大小都不一致。
zyq5945 2014-11-04
  • 打赏
  • 举报
回复
int iRows; m_conPtr->Execute((_bstr_t)szSql,(VARIANT*)&iRows,adCmdText); 肯定是不能这样强制转换的,两个数据类型大小都不一致。
jamseyang 2014-11-04
  • 打赏
  • 举报
回复
再次调试后发现是_RecordsetPtr pRecord = m_conPtr->Execute((_bstr_t)szSql,(VARIANT*)&iRows,adCmdText);这句导致Debug调试问题的,估计和ADO里面的com类型有关,改为下面这样Debug就不报错了。哪位高人可以解释下原因。

bool Test()
{
	char    szSql[64] = "select * from YF_TEST";
	int        iRows = 0;
	char    szError[512] = {0};
	char    szID[128] = {0};
	char    szName[128] = {0};
	char    szAddress[128] = {0};

	_RecordsetPtr pRst(__uuidof(Recordset));
	_CommandPtr pCmd(__uuidof(Command));

	try
	{              	
		pCmd->put_ActiveConnection(_variant_t((IDispatch*)m_conPtr));
		pCmd->CommandText=szSql;
		pRst=pCmd->Execute(NULL,NULL,adCmdText);

		strcpy(szID, (char*)(_bstr_t)pRst->GetCollect("ID"));
		strcpy(szName, (char*)(_bstr_t)pRst->GetCollect("Name"));
		strcpy(szAddress, (char*)(_bstr_t)pRst->GetCollect("Address"));   
		pRst->Close();

	}
	catch(_com_error e)
	{       
		printf("%s\n", e.ErrorMessage());   
		exit(-1);
	}

	return true;
}
SiGoYi 2014-11-04
  • 打赏
  • 举报
回复
我感觉是下面两句有问题, char szSql[64] = "select * from TEST"; _RecordsetPtr pRecord = m_conPtr->Execute((_bstr_t)szSql,(VARIANT*)&iRows,adCmdText); 问题出现在(_bstr_t)szSql,由于szSql是char数据,而(_bstr_t)是宽字符。 楼主可以把char szSql[64] = "select * from TEST";改在(_bstr_t)类型来式式,使用sysallocstring来创建一个(_bstr_t)
赵4老师 2014-11-04
  • 打赏
  • 举报
回复
引用 10 楼 zyq5945 的回复:
1.ADO在读取记录之前要先判断是否有记录,对空记录进行读取会报错的 2.数据库_variant_t的NULL值是不能这样强制转换的 可以看下这里的例子,C++熟悉的话推荐用ADO类方便一些。
应该说到点子上了。 慎用强制类型转换。
jamseyang 2014-11-04
  • 打赏
  • 举报
回复
引用 8 楼 zhao4zhong1 的回复:
char    szSql[64] = "select * from YF_TEST";
改为
char    szSql[64] = "select * from YF_TEST where rownum<1000";//防止表YF_TEST万一有≥100万条记录
试试看。
这样是没用的,数据库里面只有一条测试数据。
引用 9 楼 zhao4zhong1 的回复:
或者 static char szSql[64] = "select * from YF_TEST"; int iRows = 0; static char szError[512] = {0}; static char szID[128] = {0}; static char szName[128] = {0}; static char szAddress[128] = {0}; 在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。
都改为静态变量后Debug没有报错了,但想不通是Test函数里定义的所有字符数组加起来不超过1024字节啊!
zyq5945 2014-11-03
  • 打赏
  • 举报
回复
1.ADO在读取记录之前要先判断是否有记录,对空记录进行读取会报错的 2.数据库_variant_t的NULL值是不能这样强制转换的 可以看下这里的例子,C++熟悉的话推荐用ADO类方便一些。
赵4老师 2014-11-03
  • 打赏
  • 举报
回复
或者 static char szSql[64] = "select * from YF_TEST"; int iRows = 0; static char szError[512] = {0}; static char szID[128] = {0}; static char szName[128] = {0}; static char szAddress[128] = {0}; 在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。
赵4老师 2014-11-03
  • 打赏
  • 举报
回复
char    szSql[64] = "select * from YF_TEST";
改为
char    szSql[64] = "select * from YF_TEST where rownum<1000";//防止表YF_TEST万一有≥100万条记录
试试看。
赵4老师 2014-11-03
  • 打赏
  • 举报
回复
char szID[128] = {0}; char szName[128] = {0}; char szAddress[128] = {0}; strncpy(szID, (char*)(_bstr_t)pRecord->GetCollect("ID"),127);szID[127]=0; strncpy(szName, (char*)(_bstr_t)pRecord->GetCollect("Name"),127);szName[127]=0; strncpy(szAddress, (char*)(_bstr_t)pRecord->GetCollect("Address"),127);szAddress[127]=0; 和 char szID[128] = {0}; strncpy(szID, (char*)(_bstr_t)pRecord->GetCollect("ID"), 127); char szName[128] = {0}; strncpy(szName, (char*)(_bstr_t)pRecord->GetCollect("Name"), 127); char szAddress[128] = {0}; strncpy(szAddress, (char*)(_bstr_t)pRecord->GetCollect("Address"), 127); strncpy(szID, (char*)(_bstr_t)pRecord->GetCollect("ID"), 127); char szName[128] = {0}; strncpy(szName, (char*)(_bstr_t)pRecord->GetCollect("Name"), 127); char szAddress[128] = {0}; strncpy(szAddress, (char*)(_bstr_t)pRecord->GetCollect("Address"), 127); 不是一回事!
oyljerry 2014-11-03
  • 打赏
  • 举报
回复
单步调试一下,看你具体出错的位置。
jamseyang 2014-11-03
  • 打赏
  • 举报
回复
按照赵老师说的函数返回时还是报同样的错!

bool Test()
{
	char    szSql[64] = "select * from YF_TEST";
	int        iRows = 0;
	char    szError[512] = {0};
	char     szID[128] = {0};
	char     szName[128] = {0};
	char     szAddress[128] = {0};

	try
	{
		_RecordsetPtr  pRecord  = m_conPtr->Execute((_bstr_t)szSql,(VARIANT*)&iRows,adCmdText);
		strncpy(szID, (char*)(_bstr_t)pRecord->GetCollect("ID"),127);szID[127]=0;
		strncpy(szName, (char*)(_bstr_t)pRecord->GetCollect("Name"),127);szName[127]=0;
		strncpy(szAddress, (char*)(_bstr_t)pRecord->GetCollect("Address"),127);szAddress[127]=0;
		pRecord->Close();

	}
	catch(_com_error e)
	{       
		printf("%s\n", e.ErrorMessage());     
			exit(-1);
	}

	return true;
}

jamseyang 2014-11-03
  • 打赏
  • 举报
回复
引用 2 楼 zhao4zhong1 的回复:
bool Test()
{
    char    szSql[64] = "select * from TEST";
    int        iRows = 0;
    char    szError[512] = {0};
    char     szID[128] = {0};
    char     szName[128] = {0};
    char     szAddress[128] = {0};

    try
    {
        _RecordsetPtr  pRecord  = m_conPtr->Execute((_bstr_t)szSql,(VARIANT*)&iRows,adCmdText);
        strncpy(szID, (char*)(_bstr_t)pRecord->GetCollect("ID"),127);szID[127]=0;
        strncpy(szName, (char*)(_bstr_t)pRecord->GetCollect("Name"),127);szName[127]=0;
        strncpy(szAddress, (char*)(_bstr_t)pRecord->GetCollect("Address"),127);szAddress[127]=0
        pRecord->Close();
 
    }
    catch(_com_error e)
    {       
        printf("%s\n", e.ErrorMessage())       
        exit(-1);
    }
 
    return true;
}
感谢回复,我按照老师说的,改成下面这样,函数返回后报同样的错误!

char 	szID[128] = {0};
strncpy(szID, (char*)(_bstr_t)pRecord->GetCollect("ID"), 127);
char 	szName[128] = {0};
strncpy(szName, (char*)(_bstr_t)pRecord->GetCollect("Name"), 127);
char 	szAddress[128] = {0};
strncpy(szAddress, (char*)(_bstr_t)pRecord->GetCollect("Address"), 127);	
jamseyang 2014-11-03
  • 打赏
  • 举报
回复
引用 1 楼 zzz3265 的回复:
strcpy(szID, (char*)(_bstr_t)pRecord->GetCollect("ID")); strcpy(szName, (char*)(_bstr_t)pRecord->GetCollect("Name")); strcpy(szAddress, (char*)(_bstr_t)pRecord->GetCollect("Address")); strcpy 会导致溢出, 你调试看看这几个变量的值是否超出大小
谢谢回复,应该不是缓冲区过小导致问题的。 我代码改成下面这样函数返回后报同样的错误。

string strID = (char*)(_bstr_t)pRecord->GetCollect("ID");
string strName = (char*)(_bstr_t)pRecord->GetCollect("Name");
string strAddress = (char*)(_bstr_t)pRecord->GetCollect("Address");
赵4老师 2014-11-03
  • 打赏
  • 举报
回复
bool Test()
{
    char    szSql[64] = "select * from TEST";
    int        iRows = 0;
    char    szError[512] = {0};
    char     szID[128] = {0};
    char     szName[128] = {0};
    char     szAddress[128] = {0};

    try
    {
        _RecordsetPtr  pRecord  = m_conPtr->Execute((_bstr_t)szSql,(VARIANT*)&iRows,adCmdText);
        strncpy(szID, (char*)(_bstr_t)pRecord->GetCollect("ID"),127);szID[127]=0;
        strncpy(szName, (char*)(_bstr_t)pRecord->GetCollect("Name"),127);szName[127]=0;
        strncpy(szAddress, (char*)(_bstr_t)pRecord->GetCollect("Address"),127);szAddress[127]=0
        pRecord->Close();
 
    }
    catch(_com_error e)
    {       
        printf("%s\n", e.ErrorMessage())       
        exit(-1);
    }
 
    return true;
}
Yofoo 2014-11-03
  • 打赏
  • 举报
回复
strcpy(szID, (char*)(_bstr_t)pRecord->GetCollect("ID")); strcpy(szName, (char*)(_bstr_t)pRecord->GetCollect("Name")); strcpy(szAddress, (char*)(_bstr_t)pRecord->GetCollect("Address")); strcpy 会导致溢出, 你调试看看这几个变量的值是否超出大小

4,011

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 数据库
社区管理员
  • 数据库
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧