看了一下源代码,只是将CStringData::nDataLength改为内存块中字符的实际长度,
不该也没有什么问题呀?以下是msdn的CString::ReleaseBuffer中的例子CString s;
s = "abc";
LPTSTR p = s.GetBuffer( 1024 );
strcpy(p, "abc"); // use the buffer directly
ASSERT( s.GetLength() == 3 ); // String length = 3
s.ReleaseBuffer(); // Surplus memory released, p is now invalid.
ASSERT( s.GetLength() == 3 ); // Length still 3在调用了s.ReleaseBuffer();后,msdn说p is invalid,但是还是可以在用
strcpy(p,"rickey");
AfxMessage(p);
没有什么问题呀???
不该也没有什么问题呀?以下是msdn的CString::ReleaseBuffer中的例子CString s;
s = "abc";
LPTSTR p = s.GetBuffer( 1024 );
strcpy(p, "abc"); // use the buffer directly
ASSERT( s.GetLength() == 3 ); // String length = 3
s.ReleaseBuffer(); // Surplus memory released, p is now invalid.
ASSERT( s.GetLength() == 3 ); // Length still 3在调用了s.ReleaseBuffer();后,msdn说p is invalid,但是还是可以在用
strcpy(p,"rickey");
AfxMessage(p);
没有什么问题呀???
解决方案 »
- [原创&交流]DLL封装框架视图经验总结<一>
- 为什么提示此错误?Run-Time Check Failure #2
- 句中的server、in-place和container是什么意思?整段话又是什么意思?
- 一个类与数据库中多个表连接的问题!急!!!
- vc写的程序不做安装包怎么发布
- 关于recv的问题
- 如何实现在对话框的picture控件中画图
- 出现这种错误怎么办?:LINK : fatal error LNK1104: cannot open file "mfcs42u.lib"
- CtreeCtrl的问题
- 请问DevStudio是什么工具,在哪里有下载
- 硬件资料?
- 关于界面大小改变是消息的处理?
如果你想要使你的CString对象的缓冲区直接指向别人,那么CString对象内部的缓冲区指针谁来释放?当然是你!办法就是调用ReleaseBuffer。其次,内存invalid并不代表不能用。如果有这样的代码:
int *p = new int;//假设p==0xffff2222
delete p;//p is invalid
//但是此时p==0xffff2222
在这之后,如果你再使用p就不一定安全了。也可能有这种情况:
在delete p之后,使用p之前,恰好操作系统中的任何线程都没有使用地址0xffff2222,那么这是你的代码也不会除错,只是其内容是一些随机值。
所以,你应该保持这样的风格:
在delete一个指针之后把他赋值为0。
而0x00000000永远是不能读的,所以保证出错,及早解决问题。
CString::CString()
{
Init();
}
_AFX_INLINE void CString::Init()
{ m_pchData = afxEmptyString.m_pchData; }重新分配一块内存,把原来的数据拷贝过去,释放原来的内存.
LPTSTR CString::GetBuffer(int nMinBufLength)
{
....
// we have to grow the buffer
CStringData* pOldData = GetData();
int nOldLen = GetData()->nDataLength; // AllocBuffer will tromp it
if (nMinBufLength < nOldLen)
nMinBufLength = nOldLen;
AllocBuffer(nMinBufLength);
memcpy(m_pchData, pOldData->data(), (nOldLen+1)*sizeof(TCHAR));
GetData()->nDataLength = nOldLen;
String::Release(pOldData);
....
}如果缓冲区没有被引用,则直接将要设置长度的最后一位置零.
void CString::ReleaseBuffer(int nNewLength)
{
CopyBeforeWrite(); // just in case GetBuffer was not called if (nNewLength == -1)
nNewLength = lstrlen(m_pchData); // zero terminated ASSERT(nNewLength <= GetData()->nAllocLength);
GetData()->nDataLength = nNewLength;
m_pchData[nNewLength] = '\0';
}GetBuffer和ReleaseBuffer函数是为了解决使用strcpy时字符串会超过缓冲区大小的情况. LPCTSTR 重载操作符获得的字符串指针不能作为左值修改其中数据,因为这有可能引起指针越界或使该指针无效.所以要使用Getbuffer和ReleaseBuffer如下:
CString str;
str = "abcdef";
//strcpy(LPCTSTR(str), "1234567890");是行不通的.
LPTSTR pStr = str.GetBuffer(16); //如果不重新分配的话,可能造成 //指针越界
lstrcpy(pStr, "1234567890");
str.ReleaseBuffer(5); //释放缓冲到指定的字符串长度
现在的字符串是"12345"