MFC的 CString 学习笔记 -3

来源:互联网 发布:淘宝返利的钱返到哪里 编辑:程序博客网 时间:2024/05/06 00:58

CString Class Research (3)

 

4. CStringData Allocate and dispose.

                In prior section, we know the CStringData has two Parts, One is Header, Include 3 member variables and 1 member function, totally 12 bytes, and the other part is actual data.

                Look the following code in MFC to Allocate and Dispose CStringData and its data buffer.

 

CStringData* pData;

pData = (CStringData*)

                                new BYTE[sizeof(CStringData) + (nLen+1)*sizeof(TCHAR)];

pData->nAllocLength = nLen;

pData->nRefs = 1;

pData->data()[nLen] = '/0';

pData->nDataLength = nLen;

m_pchData = pData->data();

                MFC allocate memory as BYTE array, include CStringData and data buffer, and convert it to CStringData pointer, nLen is the length of string, and one more byte, store a ‘/0’.

                In debug mode, when the nLen <= 64, system allocates 64 bytes, when the nLen <= 128, system allocates 128 bytes....

               

delete[] (BYTE*)pData;

                To dispose buffer, because there are CStringData part (header) and data buffer part, MFC convert the CStringData* to BYTE array, then delete it.

 

5. CString operator =.

                There are two methods to set one CString’s value. If the source string is not a CString object, then MFC will allocate a new buffer to destination CString object, and use memcpy function to copy the content of source string to destination CString.m_pchData.

AllocBeforeWrite(nSrcLen);

memcpy(m_pchData, lpszSrcData, nSrcLen*sizeof(TCHAR));

GetData()->nDataLength = nSrcLen;

m_pchData[nSrcLen] = '/0';

               

In addition, if the source string is CString Object, commonly, the destination CString.m_pchData point to source CString.m_pchData. That means, the destination CString.m_pchData and the source CSting.m_pchData will point to the same address, destination CString and the source CString has the same CStringData object.

                When 2 objects share one CStringData, the nRef member variable of CStringData will be set to 2.

If (m_pchData != stringSrc.m_pchData)

{

                if ((GetData()->nRefs < 0 && GetData() != _afxDataNil) ||

                                stringSrc.GetData()->nRefs < 0)

                {

                                // actual copy necessary since one of the strings is locked

                                AssignCopy(stringSrc.GetData()->nDataLength, stringSrc.m_pchData);

                }

                else

                {

                                // can just copy references around

                                Release();

                                ASSERT(stringSrc.GetData() != _afxDataNil);

                                m_pchData = stringSrc.m_pchData;

                                InterlockedIncrement(&GetData()->nRefs);

                }

}

                Two CString share one CStringData will save system memory resource, but there is a risk, that when data in CString object’s CStringData is changed, the other CString object will be changed at the same time, that may be is not we want.

                There is a function in MFC named CopyBeforeWrite to deal with this problem:

void CString::CopyBeforeWrite()

{

                if (GetData()->nRefs > 1)

                {

                                CStringData* pData = GetData();

                                Release();

                                AllocBuffer(pData->nDataLength);

                                memcpy(m_pchData, pData->data(), (pData->nDataLength+1)*sizeof(TCHAR));

                }

                ASSERT(GetData()->nRefs <= 1);

}

                When one CString’s value will be set, MFC will check if there is any other  CString share the same CStringData object with it. If the reference bigger than 1, that means at least 2 CString object reference this CStringData object. The current, will be changed CString must create a new CStringData object to store the new value.

                In the Release() function, if the reference bigger than 1, the buffer will not delete actually.

 

6. LockBuffer() and UnLockBuffer()

                LockBuffer will set nRef member to -1, and UnlockBuffer will set nRef member to 1.

                MSDN said: While in a locked state, the string is protected in two ways:

No other string can get a reference to the data in the locked string, even if that string is assigned to the locked string.

 

The locked string will never reference another string, even if that other string is copied to the locked string.

               

                CString str1, str2;

                str2 = "abcde";

                str2.LockBuffer();

                str1 = str2;

 

                CString str3;

                str3 = "kk";

                str3.LockBuffer();

                str3 = str1;

                The str2’s buffer is locked, when set str1 equal to str2, a new buffer will created to store the str2’s value. str1 and str2 have different CStringData object.

               If the str3’s buffer is not locked, the str3 will share CStringData object with str1, but in this code, str3’s CStringData object is locked, MFC will copy the value of str1 to str3, the str3’s buffer address is not changed.

                Of course , when CString is initializion without init-value, MFC will set a system defined, empty CStringData object to it, the nRef is -1, so LockBuffer() and UnLockBuffer() is no use to system defined, empty CStringData object.

 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 狗狗呼吸急促是怎么办 狗狗着凉了呕吐怎么办 狗鼻子流黄鼻涕怎么办 刚出生婴儿睡觉不踏实怎么办 有人溺水后你该怎么办 借钱不还怎么办没欠条 私人欠货款不还怎么办 公司欠货款不还怎么办 两个人离婚一方不同意怎么办 比亚迪l3油耗高怎么办 u盘密码忘记了怎么办 主板没有m.2接口怎么办 点痣留下了疤怎么办 危险三角区长痘痘怎么办 挤了危险三角区怎么办 三角区长痘挤了怎么办 三角区发红长痘怎么办 激光祛斑碰水了怎么办 激光打痣留下坑怎么办 点痣之后留下坑怎么办 去痣留下的红印怎么办 激光点痦子留疤怎么办 激光点痣的疤痕怎么办 做完眉毛碰水了怎么办 脸上疤掉了有坑怎么办 结痂不小心抠掉怎么办 脸上肉松弛怎么办19岁 点痣留下来的疤怎么办 激光祛斑的红印怎么办 脸上疤掉了红印怎么办 痘痘发炎了红肿怎么办 脸上的斑越来越多了怎么办 点痣留下的疤痕怎么办 额头又高又大怎么办 脸太长额头太高怎么办 动车因台风停运怎么办 爸妈50了要离婚怎么办 鸿利彩票黑了钱怎么办 忘了锁屏图案怎么办 黄金被水银沾上怎么办 被股东了我该怎么办