青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

兔子的技術博客

兔子

   :: 首頁 :: 聯系 :: 聚合  :: 管理
  202 Posts :: 0 Stories :: 43 Comments :: 0 Trackbacks

留言簿(10)

最新評論

閱讀排行榜

評論排行榜

以前知道,在一個模塊中 new 一塊內存,然后在其它模塊中釋放,會導致異常。 但這次出現的問題比較古怪,剛開始根本沒想到是內存的原因。
查找原因比較曲折,但后來用虛函數的方法解決了問題,沒有修改代碼邏輯,感覺還是比較巧妙的^_^
執行環境簡單介紹如下:
一個靜態庫工程 MyShare.lib ,關鍵代碼如下:

 
// CMyObject 類部分代碼

 
class CMyObject
 {
 
public:
     CMyClient 
*m_pParent;
     
void FinalObject();            
 };
 

void CMyObject::FinalObject()
{
    
    m_pParent
->UnBand(this);    
    
}

// CMyClient 類部分代碼

class CMyClient
{
    std::map
<CMyObject *,int> m_mapObjects;
public:
    
void Band(CMyObject *pObject);
    
void UnBand(CMyObject *pObject);
};

void CMyClient::Band(CMyObject *pObject)
{
    m_mapObjects[pObject] 
= 1;
}

void CMyClient::UnBand(CMyObject *pObject)
{
    m_mapObjects.erase(pObject);            
// 這里出現異常!
}


一個引用了 MyShare.lib 的 dll 工程:MyCommon.dll,關鍵代碼如下
// 一個從 CMyObject 派生的類
class CMyCommonObject : public CMyObject
{
    
};

// 創建一個 CMyCommonObject 
CMyObject * CreateObject()
{
    
return static_cast<CMyObject *>(new CMyCommonObject);
}

// 釋放對象
void ReleaseObject(CMyObject * pObject)
{
    pObject
->FinalObject();
    delete pObject;
}

一個引用了以上兩個模塊 exe工程:MyTest.exe,關鍵代碼如下:
int main(int argc, TCHAR* argv[])
{
    CMyClient client;

    
// 調用 MyCommon.dll 中的代碼創建一個對象
    CMyObject * pObject = CreateObject();

    
// 初始化對象
    client.Band(pObject);
    pObject->m_pParent = &client;

    

    
// 使用完畢,調用 MyCommon.dll 中的代碼釋放對象
    ReleaseObject(pObject);    
}

以上代碼,在運行時,會在 m_mapObjects.erase(pObject);  處出現異常;如果單純看類的每個函數,很難看出問題,另外,工程本身比較復雜,所以一直沒有懷疑是因為不同模塊之間分配和釋放內存導致的問題。
值得注意的是,這里的 MyTest.exe 和 MyCommon.dll 中包含了同一個靜態庫,也就是說,他們之中都有 CMyObject 和 CMyClient 的二進制代碼!很容易向導的是,問題應該出在 Band 和 UnBand 。毫無疑問,以上代碼中的 client.Band 執行的是 MyTest.exe 中的代碼。那么,m_pParent->UnBand 執行的是哪里的代碼呢?之前我想當然的以為,既然 m_pParent 指針都是從 MyTest.exe 中傳遞來的,那肯定是執行的 MyTest.exe 中的代碼。后來在VC中調試時偶然發現,執行UnBand 的代碼在 MyCommon.dll  中,才突然想到,調用類的成員函數不就相當于普通函數加一個 this 參數嗎?而普通函數編譯時就確定了地址,那肯定是指向自己模塊中的二進制代碼了。 那么,m_pParent->UnBand 肯定執行的 MyCommon.dll 中的代碼!這樣問題就真相大白了:在 MyTest.exe 中向 map 加入元素,而在 MyCommon.dll  中釋放,肯定會出錯!因為加入或刪除元素極可能造成堆內存分配的變化!

現在問題找到了,怎么解決呢?如果修改代碼邏輯,則會造成其它關聯代碼的修改,想起來都有些頭痛。問題主要是函數地址,什么函數是延遲綁定地址的呢?突然想到了虛函數!從 C++ 機制我們知道,調用虛函數其實是調用虛函數表中的函數指針,而虛函數表的內容是對象分配的時候填寫的!那么,這樣就能保證,無論在哪里調用虛函數,都是調用分配該對象的模塊中的代碼!

馬上將 CMyClient 中的 Band 和 UnBand 改成虛函數,再試,問題果然消失了,而且再次用 VC 調試,發現從 MyCommon.dll  調用 UnBand 時 ,也是在MyTest.exe 中執行 !^_^
posted on 2009-09-22 14:29 會飛的兔子 閱讀(458) 評論(2)  編輯 收藏 引用 所屬分類: C++及開發環境

Feedback

# re: 不同模塊中釋放內存出錯 2009-09-23 10:55 岳...
1. 搞的太復雜了,lib/dll/exe,來回折騰,要共享代碼,要簡單清晰,只用靜態lib就行,把大量公共代碼重用,這是有多個模塊時最好;
2. dll的使用最好是私密的,不想共享代碼的;這里就會出現模塊分配內存的問題;
3. 在封裝dll時一定注意2條:
1. 輸出純虛接口,這樣容易思考,直接隔離;
2. dll內部的內存分配與釋放,都在它自己內部完成;
4. C++有很多種方式和技巧,一定要只選一種最簡單最適合自己的思考方式,不要混用,要不然根本沒時間和精力思考應用邏輯,大量時間消耗在C++本身的技巧上,得不嘗失;

呵呵。。。。。。。。。
  回復  更多評論
  

# re: 不同模塊中釋放內存出錯 2009-09-23 11:54 會飛的兔子
回復老岳:
很好,有一定道理;
1條:現在系統必須這樣,又要 lib (有些公共代碼),又要 dll(COM組件)
2、3條:同意!
4條:部分同意。我們不能為用技巧而用技巧;當程序需要技巧的時候就用技巧,畢竟‘工欲善其事,必先利其器’嘛,^_^  回復  更多評論
  

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美日韩人人澡狠狠躁视频| 欧美二区在线观看| 亚洲在线观看视频网站| 亚洲电影观看| 亚洲国产精品va在线看黑人| 最新亚洲电影| 国产精品99久久久久久久vr| 亚洲一区在线看| 久久精品国产一区二区三区| 久久精品91| 亚洲国产天堂久久综合网| 亚洲国产福利在线| 99国产一区二区三精品乱码| 亚洲一区国产精品| 久久成人这里只有精品| 久久婷婷色综合| 欧美日韩一区二区三区在线看 | 亚洲三级电影在线观看| 一区二区久久| 久久精品一级爱片| 亚洲国产一区二区三区在线播| 亚洲人成久久| 欧美一区二区三区日韩视频| 欧美电影在线观看| 国产日韩欧美成人| 亚洲靠逼com| 久久午夜影视| 亚洲视频在线一区观看| 免费日韩视频| 狠狠久久亚洲欧美| 亚洲欧美精品一区| 欧美/亚洲一区| 午夜精品网站| 国产精品高潮呻吟久久av无限| 亚洲韩国青草视频| 久久全球大尺度高清视频| 一本色道久久88精品综合| 久久精品伊人| 国产欧美精品一区二区三区介绍 | 国产精品一区久久久| 亚洲激情视频在线| 久久久久久久久综合| 亚洲视频一区在线| 欧美日韩小视频| 亚洲经典在线| 欧美**字幕| 久久综合伊人77777尤物| 国产日本欧美一区二区三区在线| 一本色道88久久加勒比精品 | 亚洲欧美综合| 国产精品免费看片| 亚洲欧美制服中文字幕| 一区二区久久久久| 欧美视频精品在线观看| 中文亚洲字幕| 国产精品一区二区黑丝| 国精品一区二区| 欧美伊人久久久久久久久影院 | 亚洲精品国产精品国自产在线| 久久综合电影| 免费成人高清在线视频| 在线国产欧美| 亚洲二区视频| 欧美日韩国产首页在线观看| 一区二区三区精密机械公司| 日韩亚洲一区在线播放| 欧美网站在线| 久久精品日产第一区二区三区| 欧美一区二区视频97| 尤物九九久久国产精品的特点 | 欧美一区二区三区免费观看| 国产亚洲激情在线| 久久在线免费观看| 久久久久久久尹人综合网亚洲| 一区在线影院| 亚洲国产一区二区a毛片| 欧美日韩欧美一区二区| 欧美在线观看一区二区三区| 欧美一区二粉嫩精品国产一线天| 国产综合色产| 亚洲精品久久久蜜桃| 欧美午夜片在线免费观看| 欧美一区=区| 久久夜色精品国产欧美乱| 一区二区三区欧美| 欧美在线一级视频| 亚洲免费观看高清在线观看| 亚洲视频一区二区| 在线成人激情黄色| 日韩视频免费观看| 国产一级揄自揄精品视频| 亚洲大片av| 国产精品第13页| 欧美 日韩 国产 一区| 国产精品成人一区二区艾草| 免费在线观看日韩欧美| 欧美日韩在线视频一区| 久久香蕉国产线看观看网| 欧美啪啪一区| 猫咪成人在线观看| 国产精品日韩| 欧美国产日韩精品| 国产精品视频你懂的| 欧美国产综合视频| 国产日韩欧美在线播放不卡| 亚洲黑丝一区二区| 激情视频亚洲| 亚洲午夜久久久| 99精品欧美一区二区三区综合在线| 欧美一级久久久久久久大片| 99在线精品视频| 久久视频精品在线| 欧美国产亚洲视频| 亚洲网站啪啪| 亚洲国产综合91精品麻豆| 亚洲欧美色一区| 亚洲香蕉视频| 欧美久久久久久久久| 葵司免费一区二区三区四区五区| 国产精品高清在线| 亚洲精品一区二区三区樱花| 亚洲第一区在线观看| 欧美一区二区日韩| 欧美在线在线| 国产精品一区二区你懂得 | 欧美久久久久久久久| 欧美国产日韩一区二区在线观看| 国产精品羞羞答答xxdd| 一区二区不卡在线视频 午夜欧美不卡' | 亚洲一区二区三区欧美| 欧美国产精品专区| 亚洲激情在线观看视频免费| 亚洲电影在线免费观看| 久久久蜜桃精品| 男女视频一区二区| 亚洲电影免费| 久久综合伊人77777| 欧美成人精品高清在线播放| 韩国一区二区三区在线观看 | 久久综合狠狠| 伊人久久综合97精品| 欧美一区二区三区在线看| 久久久久国产一区二区三区| 国产一区二区电影在线观看| 久久aⅴ国产紧身牛仔裤| 久久久久国产免费免费| 永久域名在线精品| 欧美黄色日本| 亚洲一区二区视频在线观看| 欧美在线免费视屏| 一区二区三区在线观看国产| 久久性天堂网| 亚洲精品一区在线观看| 小黄鸭精品密入口导航| 国内伊人久久久久久网站视频| 久久久久国产精品厨房| 欧美激情一区二区三区在线视频观看| 亚洲精品一区在线观看香蕉| 欧美体内she精视频| 欧美一区三区二区在线观看| 欧美国产一区二区在线观看| 一区二区欧美亚洲| 国产一区二区三区黄| 久久全球大尺度高清视频| 亚洲精品一线二线三线无人区| 亚洲免费人成在线视频观看| 国内成人精品2018免费看| 免费影视亚洲| 亚洲在线一区二区| 亚洲成人在线视频网站| 亚洲视频1区| 在线成人亚洲| 一区二区三区精品久久久| 欧美在线观看一区| 亚洲美女尤物影院| 国产一区二区三区久久| 欧美日韩美女在线| 欧美中文在线免费| 洋洋av久久久久久久一区| 免费观看亚洲视频大全| 国产精品99久久久久久有的能看| 一区国产精品| 欧美大片一区二区| 午夜精品电影| 99ri日韩精品视频| 国语自产偷拍精品视频偷 | 影院欧美亚洲| 国产精品亚洲一区| 欧美日韩无遮挡| 欧美大片第1页| 美女视频一区免费观看| 亚洲男人第一网站| 99国产精品99久久久久久粉嫩| 另类综合日韩欧美亚洲| 久久福利影视| 欧美一二三区精品| 亚洲一区二区三区激情| 日韩视频欧美视频| 亚洲韩国青草视频| 亚洲激情校园春色|