精解CString類的GetBuffer,ReleaseBuffer 函數(VC++)

原創   精解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纔是使內存空間大小變化的罪魁禍首.

 

有興趣的可以測試一下就知道了!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章