看到这样一个例子:
• GetBuffer和ReleaseBuffer是一套需要配合使用的函数
CString csStr;
LPTSTR lpsz = csStr.GetBuffer(100);
lpsz[0] = 'a';
lpsz[1] = 'b';
lpsz[2] = '\0';
csStr.ReleaseBuffer();
int nLength = csStr.GetLength();
/* n的值为2 */
• GetBufferSetLength相对比较容易理解, 它申请一个指定长度的空间, 即使里面最终保存的字符串长度小于申请的空间长度, 也不会将多余空间释放. 
CString csStr;
LPTSTR lpsz = csStr.GetBufferSetLength(100);
lpsz[0] = 'a';
lpsz[1] = 'b';
lpsz[2] = '\0';
int nLength = csStr.GetLength();
/* n的值还是为100 */
但是总感觉GetBufferSetLength返回的还是一个LPTSTR,也就是char*,此时分配出来的临时缓冲区既可以用char*指针操作,又可以用csStr来操作,这样不是会出现意外的错误吗?求助高手帮忙解释一下。
对了,还有求助高手说明一下GetBuffer和GetBufferSetLength的区别,以及在什么情况下用哪个?谢谢!!!

解决方案 »

  1.   

    楼主可以跟踪进CString的这两个函数去看看啊!
      

  2.   

    GetBufferSetLength的缓冲区是会出现意外操作的.同样GetBuffer(n)得到的缓冲区也是会出现意外操作的.
    如下面的代码就会出错
    LPTSTR lpsz = str.GetBufferSetLength(3);
    // i = str.GetLength();
    lpsz[0] = 'a';
    lpsz[1] = 'a';
    lpsz[2] = 'b';
    lpsz[3] = 'b';
    lpsz[4] = 'b';
    而且调用GetBufferSetLength后,如下面代码
    CString str;
    int i = str.GetLength();//i = 0
    LPTSTR lpsz = str.GetBufferSetLength(3);(自动调用ReleaseBuffer)
    int j = str.GetLength();//j=3
    str += "bbb";
    int k = str.GetLength();//k=6而用
    CString str;
    int i = str.GetLength();//i = 0
    LPTSTR lpsz = str.GetBuffer(8);(自动调用ReleaseBuffer)
             int j = str.GetLength();//j=0
             strcpy(lpsz, "1234");
    int k = str.GetLength();//k=0
             str.ReleaseBuffer();
    int l = str.GetLength();//l=4也就是说如果你知道要赋值的字符串的长度的话就可以用GetBufferSetLength,这样就不用调用ReleaseBuffer,反之就要用GetBuffer比较好了.
      

  3.   


    本来不应该返回内部指针的,但可能为了需要才返回这样返回之后你才指针的修改CString内部不知情,所以需要ReleaseBuffer通知它可能已经修改
      

  4.   


    LPTSTR CString::GetBufferSetLength(int nNewLength)
    {
    ASSERT(nNewLength >= 0); GetBuffer(nNewLength);
    GetData()->nDataLength = nNewLength;
    m_pchData[nNewLength] = '\0';
    return m_pchData;
    }LPTSTR CString::GetBuffer(int nMinBufLength)
    {
    ASSERT(nMinBufLength >= 0); if (GetData()->nRefs > 1 || nMinBufLength > GetData()->nAllocLength)
    {
    #ifdef _DEBUG
    // give a warning in case locked string becomes unlocked
    if (GetData() != _afxDataNil && GetData()->nRefs < 0)
    TRACE0("Warning: GetBuffer on locked CString creates unlocked CString!\n");
    #endif
    // 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;
    CString::Release(pOldData);
    }
    ASSERT(GetData()->nRefs <= 1); // return a pointer to the character storage for this string
    ASSERT(m_pchData != NULL);
    return m_pchData;
    }重新分配了字符串长度你的操作:
    LPTSTR lpsz = str.GetBufferSetLength(3); <--- 新找度为3//i = str.GetLength();
    lpsz[0] = 'a';
    lpsz[1] = 'a';
    lpsz[2] = 'b';
    lpsz[3] = 'b';  <-- ??????????
    lpsz[4] = 'b';  <-- ?????????? 放不下了想这样操作可以直接 + 啊