CString中的异常---特别紧急,紧急,救我一把

jinxuliang 2006-02-24 08:23:09
程序连续运转三天过后,在debug版本下出现如下提示:
Debug Assertion Failed
Progtam:c:\pepoleorientation\pd.exe
File:e:\Program files\microsoft viusal studio.net 2003\vc7\atlmfc\include\atlsimpstr.h
Line:778
Expression:pOldData->nAllocLength<nLength
For information on how you program can cause an assertion
failue,see the visual c++ documentation on asserts
(Press Retry to debug the application)
终止   重试    忽略
--------------------------------------------
我看了提示文件的源码
ATL_NOINLINE void Reallocate( int nLength )
{
CStringData* pOldData = GetData();
ATLASSERT( pOldData->nAllocLength < nLength );////这里是778行
IAtlStringMgr* pStringMgr = pOldData->pStringMgr;
CStringData* pNewData = pStringMgr->Reallocate( pOldData, nLength, sizeof( XCHAR ) );
if( pNewData == NULL )
{
ThrowMemoryException();
}
Attach( pNewData );
}
---------------------------------------
ATLASSERT( pOldData->nAllocLength < nLength );////这里是778行
请问大家可能造成这个错误的常见操作是那些?举个示例.推荐个标准写法.
...全文
531 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
jinxuliang 2006-02-26
  • 打赏
  • 举报
回复
郁闷等待下一次出问题,无奈
jinxuliang 2006-02-25
  • 打赏
  • 举报
回复
我可以很确定的说
用了GetBuffer就ReleaseBuffer
但是我不知道这样有没有潜在问题,理论上好象没有
while(true)
{
CString m_str;
m_str=" ";
......

}
jinxuliang 2006-02-25
  • 打赏
  • 举报
回复
这次弄郁闷了
Snow_Ice11111 2006-02-24
  • 打赏
  • 举报
回复
用CString.Format("%d",a)类似这种方法把数值转换为字符时一定要注意这个“%d”,不要千篇一律地用“%d”,根据实际情况有时要用“%hd”、“%ud”之类的。
lisypro 2006-02-24
  • 打赏
  • 举报
回复
UP
jinxuliang 2006-02-24
  • 打赏
  • 举报
回复
最后一招了
把编译环境挂上去跟踪
蒋晟 2006-02-24
  • 打赏
  • 举报
回复
check the call stack
watch the value of all local and mamber variables
jinxuliang 2006-02-24
  • 打赏
  • 举报
回复
各位大侠:
  我现在比较头痛的是,此问题一般至少要连续运行好几天才出现.靠写日志估计很难发现问题.
he_sl 2006-02-24
  • 打赏
  • 举报
回复
Debug版本?不能调试吗?
或者想法加输出语句
Jimmy_Xia 2006-02-24
  • 打赏
  • 举报
回复
楼主,其实这样没有任何侧重点的分析要找出问题是很难的,我建议:
重载CString类,然后在这个新类里面添加一个写文件的函数,将原先所有调用CString类的地方改成调用你自己的CMyString类,同时记录下调用的位置写到文件里去。只有找到了出问题的地方(可能是多个,但是肯定有相同的问题),就可以对症下药了。
moany 2006-02-24
  • 打赏
  • 举报
回复
CString占用内存比较大,尤其是循环创建一个CString局部变量时,由于变量是系统自己释放,有时候可能释放的不及时,就容易出问题。所以说在循环里面最好不要创建CString局部变量。
jinxuliang 2006-02-24
  • 打赏
  • 举报
回复
ydfivy(我就是一送外卖的) ( ) 信誉:98 2006-02-24 09:04:00 得分: 0


不知道你代码用没用格式化函数.
如果格式不对的话,很可能造成内存块分配错误.



-----------------------------------------------------------------------------
使用了大量的格式化函数
比如
m_strSelect.Format("INSERT INTO deviceinformation\
(Minenumber, StationNumber, StationType, StationAddress,IPAddress,CuriseNumber,RecordRunLog,ExecptionAlarm,DeviceGroup,SecQuee,UpDownWellStation)\
values(%d,%d,%d,'%s','%s',%d,%d,%d,%d,%d,%d)",atoi(m_csNet.GetMineNumber()),m_iPointNumber,m_iStationType,m_strSetupAddress,m_strIP,m_iCuriseNumber,m_iRunLogReport,m_iExecptionAlarm,m_iGroupNumber,m_iSQ,m_UDWStation);
一个傻冒 2006-02-24
  • 打赏
  • 举报
回复
最典型的一个就是用来描述内存块属性的属性值和实际的值不一致。出现这个问题的原因就是Cstring为了方便某些应用,提供了一些operations,这些operation可以直接返回内存块中的字符串的地址值,用户可以通过对这个地址值指向的地址进行修改,但是,修改后又没有调用相应的operations1使CstringData中的值来保持一致。比如,用户可以首先通过operations得到字符串地址,然后将一些新的字符增加到这个字符串中,使得字符串的长度增加,但是,由于是直接通过指针修改的,所以描述该字符串长度的CstringData中的nDataLength却还是原来的长度,因此当通过GetLength获取字符串长度时,返回的必然是不正确的。
一个傻冒 2006-02-24
  • 打赏
  • 举报
回复
不知道你代码用没用格式化函数.
如果格式不对的话,很可能造成内存块分配错误.
jinxuliang 2006-02-24
  • 打赏
  • 举报
回复
没有使用CString的指针
只做了简单的操作赋值
比如
CString cc;
cc="";
和Mid,Right,Left,Format等操作
herman~~ 2006-02-24
  • 打赏
  • 举报
回复
关注
jinxuliang 2006-02-24
  • 打赏
  • 举报
回复
这样使用了GetBuffer应该没有问题吧?

::GetPrivateProfileString("Connect","Server","127.0.0.1",m_strServerName.GetBuffer(50),50,".\\InitConfig.Ini");
::GetPrivateProfileString("Connect","UserName","smilefox",m_strUserName.GetBuffer(50),50,".\\InitConfig.Ini");
::GetPrivateProfileString("Connect","PassWord","xqw8089",m_strPassWord.GetBuffer(50),50,".\\InitConfig.Ini");
::GetPrivateProfileString("Connect","Database","PepoleOrientation",m_strDBName.GetBuffer(50),50,".\\InitConfig.Ini");
::GetPrivateProfileString("Connect","BKDataBase","BKPepoleOrientation",m_strBKDB.GetBuffer(50),50,".\\InitConfig.Ini");
::GetPrivateProfileString("Connect","BKHostIP","",m_strBKHostIP.GetBuffer(50),50,".\\InitConfig.Ini");
m_iDelayTime=::GetPrivateProfileInt("Connect","DelayTime",10,".\\InitConfig.Ini");
m_iConnFlag=::GetPrivateProfileInt("Connect","ConnFlag",0,".\\InitConfig.Ini");

if(m_iDelayTime<0||m_iDelayTime>30)
m_iDelayTime=10;

m_strBKHostIP.ReleaseBuffer();
m_strBKDB.ReleaseBuffer();
m_strPassWord.ReleaseBuffer();
m_strBKHostIP.Trim();
m_strServerName.ReleaseBuffer();
m_strUserName.ReleaseBuffer();
m_strDBName.ReleaseBuffer();
m_strBKDB.Trim();

m_strPassWord.Trim();


m_strServerName.Trim();

m_strUserName.Trim();

m_strDBName.Trim();
alen_ghl 2006-02-24
  • 打赏
  • 举报
回复
FORMAT 的 变量类型与格式要一致 不然运行时什么问题都有
还有对CString的指针操作问题
jinxuliang 2006-02-24
  • 打赏
  • 举报
回复
moany(长枪大戟) ( ) 信誉:100 2006-02-24 08:47:00 得分: 0


根据我的经验,CString最好少用,尤其是在一小段程序循环创建一个CString局部变量容易出问题,如果有这种情况最好是将其提出来定义一个变量,或者用其他类型代替。


--------------------------------------------------------------------------
你说的着情况在我程序中存在,我在循环中有循环创建的这种
moany 2006-02-24
  • 打赏
  • 举报
回复
根据我的经验,CString最好少用,尤其是在一小段程序循环创建一个CString局部变量容易出问题,如果有这种情况最好是将其提出来定义一个变量,或者用其他类型代替。
加载更多回复(2)

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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