您当前位置:地名问答 > 中国 > 浙江 > 杭州 > 西湖区 > 断桥残雪 > 断桥残雪地名
CString需要注意的地方(5)
更新:2017-08-18 01:51【断桥残雪地名】
导读:实际工作中,常常是对 GetBuffer 返回的值进行了修改,但是最后却忘记调用 ReleaseBuffer 来释放。而且,由于这个错误不象 new 和 delete 人人都知道的并重视的
实际工作中,常常是对GetBuffer 返回的值进行了修改,但是最后却忘记调用ReleaseBuffer 来释放。而且,由于这个错误不象new 和delete 人人都知道的并重视的,因此也没有一个检查机制来专门检查,所以最终程序中由于忘记调用ReleaseBuffer 而引起的错误被带到了发行版本中。
要避免这个错误,方法很多。但是最简单也是最有效的就是避免这种用法。很多时候,我们并不需要这种用法,我们完全可以通过其他的安全方法来实现。
比如上面的代码,我们完全可以这样写:
CString str1("This is the string 1");
int nOldLen = str1.GetLength();
str1 = "modified";
int nNewLen = str1.GetLength();
但是有时候确实需要,比如:
我们需要将一个Cstring 对象中的字符串进行一些转换, 这个转换是通过调用一个dll 里的函数Translate 来完成的,但是要命的是,不知道什么原因,这个函数的参数使用的是char* 型的:
DWORD Translate( char* pSrc, char *pDest, int nSrcLen, int nDestLen );
这个时候我们可能就需要这个方法了:
Cstring strDest;
Int nDestLen = 100;
DWORD dwRet = Translate( _strSrc.GetBuffer( _strSrc.GetLength() ),
strDest.GetBuffer(nDestLen),
_strSrc.GetLength(), nDestlen );
_strSrc.ReleaseBuffer();
strDest.ReleaseBuffer();
if ( SUCCESSCALL(dwRet) )
{
}
if ( FAILEDCALL(dwRet) )
{
}
的确,这种情况是存在的,但是,我还是建议尽量避免这种用法,如果确实需要使用,请不要使用一个专门的指针来保存GetBuffer 返回的值,因为这样常常会让我们忘记调用ReleaseBuffer 。就像上面的代码,我们可以在调用GetBuffer 之后马上就调用ReleaseBuffer 来调整Cstring 对象。
2. LPCTSTR
关于LPCTSTR 的错误常常发生在初学者身上。
例如在调用函数
DWORD Translate( char* pSrc, char *pDest, int nSrcLen, int nDestLen );
时,初学者常常使用的方法就是:
int nLen = _strSrc.GetLength();
DWORD dwRet = Translate( (char*)(LPCTSTR)_strSrc),
(char*)(LPCTSTR)_strSrc),
nLen,
nLen);
if ( SUCCESSCALL(dwRet) )
{
}
if ( FAILEDCALL(dwRet) )
{
}
他原本的初衷是将转换后的字符串仍然放在_strSrc 中,但是,当调用完Translate 以后之后再使用_strSrc 时,却发现_strSrc 已经工作不正常了。检查代码却又找不到问题到底出在哪里。
其实这个问题和第一个问题是一样的。Cstring 类已经将LPCTST 重载了。在Cstring 中LPCTST 实际上已经是一个operation 了。对LPCTST 的调用实际上和GetBuffer 是类似的,直接返回CstringData 对象中的字符串缓冲的首地址。
其C++ 代码实现是:
_AFX_INLINE CString::operator LPCTSTR() const
{ return m_pchData; }
因此在使用完以后同样需要调用ReleaseBuffer() 。
但是,这个谁又能看出来呢?
其实这个问题的本质原因出在类型转换上。LPCTSTR 返回的是一个const char* 类型,因此使用这个指针来调用Translate 编译是不能通过的。对于一个初学者,或者一个有很长编程经验的人都会再通过强行类型转换将const char* 转换为char* 。最终造成了Cstring 工作不正常,并且这样也很容易造成缓冲溢出。
通过上面对于Cstring 机制和一些容易出现的使用错误的描述,可以使我们更好的使用Cstring 。
很赞哦! (82)