关于CString的奇怪的问题,不知道大家有没有遇到过?

时间:2021-08-04 18:01:24
strTemp.Format("Hello  [%d:%d] \n", No1, No2);
ShowInList(strTemp);

strMessage.Format("World #%d#",No3);
PutIntoMQ(strMessage);

上面的代码,strTemp,strMessage都是CString变量,执行了几次之后,会出现一个奇怪的问题:
PutIntoMQ ()这个函数里面传入的值竟然是strTemp的值!!这个错误我测试10几次才会重现一次,但是确实是存在的.怎么回事?有点恐怖哦.


期待高手解答

9 个解决方案

#1


你的ShowInList();和PutIntoMQ();内部怎么处理传入的字符串?

#2


内部怎么处理传入的字符串有关系吗?这里是值传递啊.函数传入的是形参啊,到里面通过拷贝构造变成了实参,传入之后不论做什么操作对外面的变量应该没有影响才对啊.

在函数里面都做了这样的操作
PutIntoMQ(CString strInMsg)
{
strInMsg="CM_"+strInMsg;
char strMsg[256];
memset(strMsg,0,sizeof(strMsg));
sprintf(strMsg,strInMsg.GetBuffer(0));
if(g_mq.PutMsg(strMsg,strlen(strMsg))==-1)
{
CString str;
str.Format("Main Loop Thread Put Msg failed !");
AfxMessageBox(str);
}
}

难道是GetBuffer()的问题?没有释放?

#3


用了GetBuffer 一定要用releasebuffer的

#4


关注

#5


继续期待高人解答!!!

#6


难道是GetBuffer()的问题?没有释放?

用了GetBuffer,一定要ReleaseBuffer

#7


肯定是你自己的错误,好好检查吧.不要轻易怀疑编绎器

#8


用了GetBuffer,一定要ReleaseBuffer

#9


不ReleaseBuffer你将不能进行CString的任何操作!

GetBuffer

很多错误用法中最典型的一个就是Cstring:: GetBuffer ()了.查了MSDN,里面对这个operation的描述是:

 Returns a pointer to the internal character buffer for the CString object. The returned LPTSTR is not const and thus allows direct modification of CString contents。

这段很清楚的说明,对于这个operation返回的字符串指针,我们可以直接修改其中的值:

   CString str1("This is the string 1");――――――――――――――――1

   int nOldLen = str1.GetLength();―――――――――――――――――2

   char* pstr1 = str1.GetBuffer( nOldLen );――――――――――――――3

   strcpy( pstr1, "modified" );――――――――――――――――――――4

   int nNewLen = str1.GetLength();―――――――――――――――――5

通过设置断点,我们来运行并跟踪这段代码可以看出,当运行到三处时,str1的值是”This is the string 1”,并且nOldLen的值是20。当运行到5处时,发现,str1的值变成了”modified”。也就是说,对GetBuffer返回的字符串指针,我们将它做为参数传递给strcpy,试图来修改这个字符串指针指向的地址,结果是修改成功,并且Cstring对象str1的值也响应的变成了” modified”。但是,我们接着再调用str1.GetLength()时却意外的发现其返回值仍然是20,但是实际上此时str1中的字符串已经变成了” modified”,也就是说这个时候返回的值应该是字符串” modified”的长度8!而不是20。现在Cstring工作已经不正常了!这是怎么回事?

很显然,str1工作不正常是在对通过GetBuffer返回的指针进行一个字符串拷贝之后的。
 
再看MSDN上的关于这个operation的说明,可以看到里面有这么一段话:

If you use the pointer returned by GetBuffer to change the string contents, you must call ReleaseBuffer before using any other CString member functions.

原来在对GetBuffer返回的指针使用之后需要调用ReleaseBuffer,这样才能使用其他Cstring的operations。上面的代码中,我们在4-5处增建一行代码:str2.ReleaseBuffer(),然后再观察nNewLen,发现这个时候已经是我们想要的值8了。

#1


你的ShowInList();和PutIntoMQ();内部怎么处理传入的字符串?

#2


内部怎么处理传入的字符串有关系吗?这里是值传递啊.函数传入的是形参啊,到里面通过拷贝构造变成了实参,传入之后不论做什么操作对外面的变量应该没有影响才对啊.

在函数里面都做了这样的操作
PutIntoMQ(CString strInMsg)
{
strInMsg="CM_"+strInMsg;
char strMsg[256];
memset(strMsg,0,sizeof(strMsg));
sprintf(strMsg,strInMsg.GetBuffer(0));
if(g_mq.PutMsg(strMsg,strlen(strMsg))==-1)
{
CString str;
str.Format("Main Loop Thread Put Msg failed !");
AfxMessageBox(str);
}
}

难道是GetBuffer()的问题?没有释放?

#3


用了GetBuffer 一定要用releasebuffer的

#4


关注

#5


继续期待高人解答!!!

#6


难道是GetBuffer()的问题?没有释放?

用了GetBuffer,一定要ReleaseBuffer

#7


肯定是你自己的错误,好好检查吧.不要轻易怀疑编绎器

#8


用了GetBuffer,一定要ReleaseBuffer

#9


不ReleaseBuffer你将不能进行CString的任何操作!

GetBuffer

很多错误用法中最典型的一个就是Cstring:: GetBuffer ()了.查了MSDN,里面对这个operation的描述是:

 Returns a pointer to the internal character buffer for the CString object. The returned LPTSTR is not const and thus allows direct modification of CString contents。

这段很清楚的说明,对于这个operation返回的字符串指针,我们可以直接修改其中的值:

   CString str1("This is the string 1");――――――――――――――――1

   int nOldLen = str1.GetLength();―――――――――――――――――2

   char* pstr1 = str1.GetBuffer( nOldLen );――――――――――――――3

   strcpy( pstr1, "modified" );――――――――――――――――――――4

   int nNewLen = str1.GetLength();―――――――――――――――――5

通过设置断点,我们来运行并跟踪这段代码可以看出,当运行到三处时,str1的值是”This is the string 1”,并且nOldLen的值是20。当运行到5处时,发现,str1的值变成了”modified”。也就是说,对GetBuffer返回的字符串指针,我们将它做为参数传递给strcpy,试图来修改这个字符串指针指向的地址,结果是修改成功,并且Cstring对象str1的值也响应的变成了” modified”。但是,我们接着再调用str1.GetLength()时却意外的发现其返回值仍然是20,但是实际上此时str1中的字符串已经变成了” modified”,也就是说这个时候返回的值应该是字符串” modified”的长度8!而不是20。现在Cstring工作已经不正常了!这是怎么回事?

很显然,str1工作不正常是在对通过GetBuffer返回的指针进行一个字符串拷贝之后的。
 
再看MSDN上的关于这个operation的说明,可以看到里面有这么一段话:

If you use the pointer returned by GetBuffer to change the string contents, you must call ReleaseBuffer before using any other CString member functions.

原来在对GetBuffer返回的指针使用之后需要调用ReleaseBuffer,这样才能使用其他Cstring的operations。上面的代码中,我们在4-5处增建一行代码:str2.ReleaseBuffer(),然后再观察nNewLen,发现这个时候已经是我们想要的值8了。