GetBuffer和ReleaseBuffer是從其父類CSimpleStringT繼承過來的。GetBuffer的作用是:“Returns a pointer to the internal character buffer”,ReleaseBuffer的作用是:“Releases control of the buffer allocated by GetBuffer.”。這兩個函數的常見用法如下:
CString str; const int bufferSize = 10; LPTSTR p = str.GetBuffer(bufferSize); _tcscpy_s(p, bufferSize, _T("abcd1234.")); // use the buffer directly str.ReleaseBuffer(); // Surplus(多余的) memory released, p is now invalid.
給GetBuffer函數傳遞的參數bufferSize,意思是:“The minimum size of the character buffer in characters. This value does not include space for a null terminator.”。對於調用ReleaseBuffer釋放內存時,是否應該帶參數,msdn是這樣說的:“If you keep track of the string length yourself, you should not append the terminating null character. You must, however, specify the final string length when you release the buffer with ReleaseBuffer. If you do append a terminating null character, you should pass –1 (the default) for the length to ReleaseBuffer, and ReleaseBuffer will perform a strlen on the buffer to determine its length.”。因為ReleaseBuffer函數的默認參數是-1,所以通常在調用ReleaseBuffer函數時省去-1參數的書寫。
還有一點非常重要,看如下示例程序:
CString str; const int bufferSize = 10; LPTSTR p = str.GetBuffer(bufferSize); _tcscpy_s(p, bufferSize, _T("abcd")); // use the buffer directly str.Append(_T("1234")); str.ReleaseBuffer(); // Surplus(多余的) memory released, p is now invalid.
當程序執行完Append函數之后,程序員期望的是str字符串里保存的字符序列是abcd1234,但實際上並不是這樣。有可能str的內容仍然為abcd,或者直接變為1234。這個問題在我之前的項目中曾經遇到過,最后才把問題定位到這里,來看msdn的注釋:“If you use the pointer returned by GetBuffer to change the string contents, you must call ReleaseBuffer before using any other CSimpleStringT member methods.”。也就是說如果程序中通過GetBuffer 函數返回的字符指針修改了字符串的內容,那么必須在使用任何其他的CString類成員函數之前先調用ReleaseBuffer。