关于CString
昨天重構(gòu)代碼的時(shí)候,這樣一段代碼:
?
CString str =_T("bbbbbbbb"); LVITEM item = GetItem(str);LVITEM CLVIItemTestDlg::GetItem(CString text) {LVITEM item;item.iItem = 0;item.iSubItem = 0;item.mask = LVIF_TEXT;item.pszText = text.GetBuffer();return item; } ?
?
返回的值讓我大跌眼鏡,返回的item中的pszText居然被清空了。
開(kāi)始我猜測(cè)是不是item的賦值函數(shù)出了問(wèn)題?最后發(fā)現(xiàn)居然問(wèn)題是出在text.GetBuffer()里面。
?
CString里面實(shí)現(xiàn)的GetBuffer()代碼如下:
?
PXSTR GetBuffer() {CStringData* pData = GetData();if( pData->IsShared() ){Fork( pData->nDataLength );}return( m_pszData ); }
?
也就是說(shuō)當(dāng)CString里面的pData被引用的次數(shù)超過(guò)1個(gè)的時(shí)候,CString就會(huì)為其重新分配空間。
再回過(guò)頭來(lái)看原來(lái)的代碼,當(dāng)傳入?yún)?shù)的時(shí)候,引用計(jì)數(shù)就會(huì)為2,到我調(diào)用text.GetBuffer()的時(shí)候,返回出來(lái)的m_pszData就是新分配并賦值過(guò)后的數(shù)據(jù),再繼續(xù)執(zhí)行,item.pszText的賦值函數(shù)并沒(méi)為其分配新的空間,而是指向的就是Cstring text剛剛新分配的地址。
當(dāng)函數(shù)返回的時(shí)候,由于CString text是臨時(shí)變量,會(huì)被析構(gòu),于是剛剛新分配的空間里面的數(shù)據(jù)就會(huì)被清空并且釋放。
?
?
?
再仔細(xì)想想,CString為啥當(dāng)引用計(jì)數(shù)為2的時(shí)候,會(huì)為其分配新的空間?
猜測(cè)如果沒(méi)有分配新的空間,那么在一個(gè)對(duì)象對(duì)數(shù)據(jù)進(jìn)行寫(xiě)操作的情況下,數(shù)據(jù)就會(huì)被鎖定,而不能被另一個(gè)對(duì)象進(jìn)行寫(xiě),這樣在多線(xiàn)程的情況下,效率就會(huì)降低,因?yàn)镃String的賦值操作太頻繁了,而要寫(xiě)這個(gè)數(shù)據(jù)的線(xiàn)程都會(huì)被堵在這里,等前一個(gè)線(xiàn)程操作結(jié)束后才能進(jìn)行操作。
分配了新的空間,就能解決這個(gè)問(wèn)題。
?
這只是個(gè)人的猜測(cè),希望大家有另外不同的想法提出!
?
?
總結(jié)
- 上一篇: 风机桨叶故障诊断(四) 正负样本准备——
- 下一篇: PID:我应该何时计算积分项?