|
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 ch [1] [2] 下一页 |