您当前位置:地名问答 > 中国 > 浙江 > 杭州 > 西湖区 > 断桥残雪 > 断桥残雪地名

CString需要注意的地方(5)

更新:2017-08-18 01:51断桥残雪地名

导读:实际工作中,常常是对 GetBuffer 返回的值进行了修改,但是最后却忘记调用 ReleaseBuffer 来释放。而且,由于这个错误不象 new 和 delete 人人都知道的并重视的

实际工作中,常常是对GetBuffer 返回的值进行了修改,但是最后却忘记调用ReleaseBuffer 来释放。而且,由于这个错误不象newdelete 人人都知道的并重视的,因此也没有一个检查机制来专门检查,所以最终程序中由于忘记调用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 重载了。在CstringLPCTST 实际上已经是一个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)

相关文章