一:關(guān)于糾錯(cuò),MFC和ATL中智能指針的應(yīng)用
1:在Windows中如何方便的查看當(dāng)前進(jìn)程使用的內(nèi)存。
雖然代碼簡(jiǎn)單,但對(duì)糾錯(cuò)時(shí)有大用處,不用不停的通過(guò)切換任務(wù)管理器來(lái)查看內(nèi)存使用。代碼如下:
UINT C_BaseUtil::getProcessMemoryUsed()
{
UINT uiTotal = 0L;
HANDLE hProcess = ::GetCurrentProcess();
PROCESS_MEMORY_COUNTERS pmc;
if(::GetProcessMemoryInfo(hProcess,&pmc,sizeof(pmc)))
uiTotal = pmc.WorkingSetSize;
return uiTotal;
}
注意:由于內(nèi)存使用會(huì)是一個(gè)不穩(wěn)定的過(guò)程,所以,需要在程序穩(wěn)定時(shí)進(jìn)行調(diào)用,才能準(zhǔn)確。
2:在使用Com的Dispatch指針時(shí),如果不使用COM智能指針,容易出現(xiàn)的錯(cuò)誤。
2.1:忘記在所有出口釋放指針。
如:
IXMLDOMDocument *pDoc = NULL;
CoCreateInstance(...)
……
pDoc->Release();
錯(cuò)誤:如果中間代碼發(fā)生異常,則pDoc未能正常釋放,造成內(nèi)存泄露。
2.2:重復(fù)使用同一指針變量,導(dǎo)致中間生成的Dispatch指針未能釋放。
IXMLDOMNode *pNode = NULL;
if(FAILED(pDoc->selectSingleNode(_bstr_t("Workbook"), &pNode)) || pNode==NULL)
throw(_T("selectSingleNode failed!"));
if(FAILED(pDoc->selectSingleNode(_bstr_t("Workbook"), &pNode)) || pNode==NULL)
throw(_T("selectSingleNode failed!"));
錯(cuò)誤:pNode未釋放就開(kāi)始第二次調(diào)用,造成內(nèi)存泄露。或者類似pNode = pNode2的這種寫(xiě)法,也隨手就出問(wèn)題了。必須調(diào)用if(pNode) {pNode->Release();pNode=NULL;}
3:使用MFC提供的Com智能指針解決上述問(wèn)題。
注意:可通過(guò)查看源碼,看到#import生成的智能指針的原型是_com_ptr_t。
3.1:
IXMLDOMDocumentPtr docPtr = NULL;
docPtr.CreateInstance(...)
……
這下不會(huì)有問(wèn)題了,因?yàn)閐ocPtr在析構(gòu)時(shí)會(huì)有正確的釋放處理。
3.2:
IXMLDOMNodePtr nodePtr = NULL;
if(FAILED(pDoc->selectSingleNode(_bstr_t("Workbook"), &nodePtr)) || nodePtr==NULL)
throw(_T("selectSingleNode failed!"));
if(FAILED(pDoc->selectSingleNode(_bstr_t("Workbook"), &nodePtr)) || nodePtr==NULL)
throw(_T("selectSingleNode failed!"));
不會(huì)出錯(cuò)了,因?yàn)開(kāi)com_ptr_t重載了&操作符,在取指針時(shí),有如下操作,嘿。
Interface** operator&() throw()
{
_Release();
m_pInterface = NULL;
return &m_pInterface;
}
3.3: nodePtr = nodePrt2 ,也不會(huì)有問(wèn)題:
仔細(xì)查看源碼,在=操作符中會(huì)調(diào)用Attach,而Attach的做法是:會(huì)先調(diào)用_Release();
3.4:再看看值傳遞:拷貝構(gòu)造函數(shù)如下
template<> _com_ptr_t(const _com_ptr_t& cp) throw()
: m_pInterface(cp.m_pInterface)
{
_AddRef();
}
嗯,也不會(huì)有問(wèn)題。
1:在Windows中如何方便的查看當(dāng)前進(jìn)程使用的內(nèi)存。
雖然代碼簡(jiǎn)單,但對(duì)糾錯(cuò)時(shí)有大用處,不用不停的通過(guò)切換任務(wù)管理器來(lái)查看內(nèi)存使用。代碼如下:
UINT C_BaseUtil::getProcessMemoryUsed()
{
UINT uiTotal = 0L;
HANDLE hProcess = ::GetCurrentProcess();
PROCESS_MEMORY_COUNTERS pmc;
if(::GetProcessMemoryInfo(hProcess,&pmc,sizeof(pmc)))
uiTotal = pmc.WorkingSetSize;
return uiTotal;
}
注意:由于內(nèi)存使用會(huì)是一個(gè)不穩(wěn)定的過(guò)程,所以,需要在程序穩(wěn)定時(shí)進(jìn)行調(diào)用,才能準(zhǔn)確。
2:在使用Com的Dispatch指針時(shí),如果不使用COM智能指針,容易出現(xiàn)的錯(cuò)誤。
2.1:忘記在所有出口釋放指針。
如:
IXMLDOMDocument *pDoc = NULL;
CoCreateInstance(...)
……
pDoc->Release();
錯(cuò)誤:如果中間代碼發(fā)生異常,則pDoc未能正常釋放,造成內(nèi)存泄露。
2.2:重復(fù)使用同一指針變量,導(dǎo)致中間生成的Dispatch指針未能釋放。
IXMLDOMNode *pNode = NULL;
if(FAILED(pDoc->selectSingleNode(_bstr_t("Workbook"), &pNode)) || pNode==NULL)
throw(_T("selectSingleNode failed!"));
if(FAILED(pDoc->selectSingleNode(_bstr_t("Workbook"), &pNode)) || pNode==NULL)
throw(_T("selectSingleNode failed!"));
錯(cuò)誤:pNode未釋放就開(kāi)始第二次調(diào)用,造成內(nèi)存泄露。或者類似pNode = pNode2的這種寫(xiě)法,也隨手就出問(wèn)題了。必須調(diào)用if(pNode) {pNode->Release();pNode=NULL;}
3:使用MFC提供的Com智能指針解決上述問(wèn)題。
注意:可通過(guò)查看源碼,看到#import生成的智能指針的原型是_com_ptr_t。
3.1:
IXMLDOMDocumentPtr docPtr = NULL;
docPtr.CreateInstance(...)
……
這下不會(huì)有問(wèn)題了,因?yàn)閐ocPtr在析構(gòu)時(shí)會(huì)有正確的釋放處理。
3.2:
IXMLDOMNodePtr nodePtr = NULL;
if(FAILED(pDoc->selectSingleNode(_bstr_t("Workbook"), &nodePtr)) || nodePtr==NULL)
throw(_T("selectSingleNode failed!"));
if(FAILED(pDoc->selectSingleNode(_bstr_t("Workbook"), &nodePtr)) || nodePtr==NULL)
throw(_T("selectSingleNode failed!"));
不會(huì)出錯(cuò)了,因?yàn)開(kāi)com_ptr_t重載了&操作符,在取指針時(shí),有如下操作,嘿。
Interface** operator&() throw()
{
_Release();
m_pInterface = NULL;
return &m_pInterface;
}
3.3: nodePtr = nodePrt2 ,也不會(huì)有問(wèn)題:
仔細(xì)查看源碼,在=操作符中會(huì)調(diào)用Attach,而Attach的做法是:會(huì)先調(diào)用_Release();
3.4:再看看值傳遞:拷貝構(gòu)造函數(shù)如下
template<> _com_ptr_t(const _com_ptr_t& cp) throw()
: m_pInterface(cp.m_pInterface)
{
_AddRef();
}
嗯,也不會(huì)有問(wèn)題。