精解CString類的GetBuffer,ReleaseBuffer 函數(VC++) 收藏
回憶錄:(VC++)
原文地址:http://blog.csdn.net/flswahaha/archive/2008/07/25/2711991.aspx
CString str = "abcde/0cde";
輸出字符串的值爲: abcde
而字符串的長度爲 s.GetLength() 的值爲: 5
這是因爲CString對象在賦值時只檢查到'/0',後面的忽略了, 也就是說實際對象str內容爲"abcde".
而str真正的存儲空間爲6(字符串以'/0'結尾).
所以說在字符長度和實際的空間是不一樣的. 好!別跑!
請看下面有趣的程序:
CString str = "hello";
LPSTR pf = (LPSTR)(LPCSTR)s;
LPSTR pa = s.GetBuffer(0);
你可以測得 pf == pa;
LPSTR pb = s.GetBuffer(10);
你可以測得 pf != pb;
爲什麼:
我們都知道(LPSTR)(LPCSTR)s 實際指向對象str的實際字符串的內存地址, GetBuffer() 函數中的參數(其實就是重新申請的字符串的長度)如果小於等於先前的字符串長度, 則不會重新分配內存使用原來的內存所以 pf == pa, 如果大於先前的字符串長度, 則重新追加內存(也就是要複製原來的內容),
所以pf != pb.
注意GetBuffer()函數中的參數爲重新申請的字符串的長度, 實際內存的大小應再加1.
CString s = "hello";
LPSTR pf = s.GetBuffer(0);
strcpy(pf,"hi");
這時對象str 的內容爲 "hi"
但是s.GetLength()的值爲5, 如果加上一條語句:
s.ReleaseBuffer();
則s.GetLength()的值爲2
解釋:
CString對象在內存中用一個計數器來維持可用緩衝區的大小
void ReleaseBuffer( int nNewLength = -1 )
{
if( nNewLength == -1 )
{
nNewLength = StringLength( m_pszData );
}
SetLength( nNewLength );
}
很明顯ReleaseBuffer的作用就是更新字符串的長度。 CString內,GetLength獲取字符串長度並不是動態計算的,而是在賦值操作後計算並保存在一個int變量內的,當通過GetBuffer直接 修改CString時,那個int變量並不可能自動更新,於是便有了ReleaseBuffer.
CString s = "hello";
LPSTR pf = s.GetBuffer(0);
strcpy(pf,"hi");
LPSTR ps = (LPSTR)(LPCSTR)s; 字符串緩衝區的首地址
*(ps+2) = 'x';
則字符串的實際內容爲: "hixlo"
*(ps+6) = 'a'; 出錯, 因爲對象s的實際空間爲 6
而
CString s = "hello";
LPSTR pf = s.GetBuffer(10);
strcpy(pf,"hi");
LPSTR ps = (LPSTR)(LPCSTR)s; 字符串緩衝區的首地址
*(ps+2) = 'x';
*(ps+5)= '/0';
則字符串的實際內容還是爲: "hixlo"
*(ps+6) = 'a'; 可以因爲s對象的實際空間爲11
說白了 ReleaseBuffer就是更新賦值之後的字符串的長度, 而實際空間沒有根本的變化, GetBuffer纔是使內存空間大小變化的罪魁禍首.
有興趣的可以測試一下就知道了!!!