• <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>
            萬星星@豌豆莢 歡迎加入我們
            一個(gè)吃軟飯的男人!!!!!我只想寫程序####
            微博:http://weibo.com/wanlianwen
            posts - 172,  comments - 1253,  trackbacks - 0

            昨天做一個(gè)dll,代碼很快寫完了,然而使用得時(shí)候總是遇到string內(nèi)部指針刪除錯(cuò)誤,郁悶了一天,今天沒去公司,好好研究了一下。
            首先看下下面這段代碼,聲明兩個(gè)string對(duì)象:

            std:: string ??s1? = ? " wlwlxj " ;
            std::
            string ??s2? = ? " lxjwlwww " ;

            調(diào)試狀態(tài)下可以看到內(nèi)部指針:
            s1=0x00364ff9
            s2=0x00365061
            然后執(zhí)行

            s2? = ?s1;

            按下f11,進(jìn)入xstring源文件:

            _Myt & ? operator = ( const ?_Myt & ?_X)?????????// 賦值操作符
            ??
            { return ?(assign(_X));?}?????????????????????// 調(diào)用assign函數(shù)

            繼續(xù)進(jìn)入assign(_X)函數(shù):

            _Myt & ?assign( const ?_Myt & ?_X)
            ????????
            { return ?(assign(_X,? 0 ,?npos));?}???// 調(diào)用assign函數(shù)
            繼續(xù)進(jìn)入assign函數(shù),好戲都在這里面:
            _Myt&?assign(const?_Myt&?_X,?size_type?_P,?size_type?_M)
            ????????
            {if?(_X.size()?<?_P)
            ????????????_Xran();
            ????????size_type?_N?
            =?_X.size()?-?_P;
            ????????
            if?(_M?<?_N)
            ????????????_N?
            =?_M;
            ????????
            if?(this?==?&_X)
            ????????????erase((size_type)(_P?
            +?_N)),?erase(0,?_P);
            ????????
            else?if?(0?<?_N?&&?_N?==?_X.size()????????????????????????// 這個(gè)分支意思就是如果拷貝源有內(nèi)容且就是就是源本身,并且
            ????????????
            &&?_Refcnt(_X.c_str())?<?_FROZEN?-?1??????????// 源字符串引用次數(shù)少于255-1次(可見引用次數(shù)最多255次),
            ????????????
            &&?allocator?==?_X.allocator)???????????????????????????//且源字符和目的字符分配器一致
            ????????????
            {_Tidy(true);?????????????????????????????????????????????// 刪除本身
            ????????????_Ptr?
            =?(_E?*)_X.c_str();????????????????????????????????????// 復(fù)制內(nèi)容到目的串
            ????????????_Len?
            =?_X.size();
            ????????????_Res?
            =?_X.capacity();
            ????????????
            ++_Refcnt(_Ptr);?}?????????????????????????????????????????????// 增加一次引用

            ????????
            else?if?(_Grow(_N,?true))
            ????????????
            {_Tr::copy(_Ptr,?&_X.c_str()[_P],?_N);
            ????????????_Eos(_N);?}

            ????????
            return?(*this);?}

            這樣結(jié)果就是調(diào)用=號(hào)以后,s2地址和s1地址一樣,都是0x00364ff9。

            假如我們動(dòng)態(tài)庫(kù)有這樣一個(gè)類class DLL接口:

            SetString(std::string?str)
            {
            m_str?
            =?str;
            }

            在客戶調(diào)用時(shí)候:

            std::string?str?=?"wlwlxj";
            DLL?d;
            d.SetString(str);?
            //?此時(shí)沒有深拷貝,而是引用了str內(nèi)部指針地址
            在調(diào)用結(jié)束的時(shí)候,dll內(nèi)部刪除成員變量的時(shí)候,會(huì)判斷m_str內(nèi)部指針合法性,由于實(shí)際分配是在調(diào)用端,在dll內(nèi)部自然檢查指針非法。

            解決方法就是避免std::string引用計(jì)數(shù),接口處修改為SetString(const char*),這樣在dll內(nèi)部分配內(nèi)存,內(nèi)部釋放,就不會(huì)有問題。
            posted on 2006-04-18 16:23 萬連文 閱讀(7084) 評(píng)論(9)  編輯 收藏 引用 所屬分類: 模板

            FeedBack:
            # re: std::string一個(gè)極其隱晦得問題
            2006-04-18 16:55 | cf
            此是老問題了,即跨module(exe、dll)間申請(qǐng)/釋放內(nèi)存違例的問題,對(duì)發(fā)生在傳遞c++對(duì)象并使用時(shí),不僅僅發(fā)生在std::string上

            原因是由于程序中使用的內(nèi)存管理多來源于crt提供的例程,而非直接使用操作系統(tǒng)的接口,這些例程都需要維護(hù)一些module全局?jǐn)?shù)據(jù)(例如維護(hù)池、維護(hù)空閑塊、或者標(biāo)記已申請(qǐng)的塊等等,不同的實(shí)現(xiàn)中有不同的作用),當(dāng)他們被靜態(tài)連編時(shí),實(shí)際上這些“全局?jǐn)?shù)據(jù)”就不“全局”了,不同的module各自為政,每份module都有自己的“全局?jǐn)?shù)據(jù)”,自身的內(nèi)存信息不為他人所知,module A的合法內(nèi)存快自然不可能通得過module B的合法性驗(yàn)證

            解決問題的方法有:
            1、不要跨module傳遞c++對(duì)象,或者避免釋放跨module申請(qǐng)的內(nèi)存

            2、將參與合作的module統(tǒng)統(tǒng)以multithreaded dll方式鏈入crt庫(kù),讓他們的“全局”數(shù)據(jù)真正全局,注意,所有有交互的module都需要?jiǎng)討B(tài)鏈入crt,

            不推薦第二種方式
              回復(fù)  更多評(píng)論
              
            # re: std::string一個(gè)極其隱晦得問題
            2006-04-18 20:29 | christanxw
            Dll的出口函數(shù)最好是用標(biāo)準(zhǔn)的C類型。  回復(fù)  更多評(píng)論
              
            # re: std::string一個(gè)極其隱晦得問題
            2006-04-18 21:39 | 萬連文
            最好是用標(biāo)準(zhǔn)的C類型卻是是一種準(zhǔn)則。
            個(gè)人認(rèn)為:作為輸出參數(shù)可以通過指針避免,輸入?yún)?shù)一般沒有問題,上面那個(gè)string僅僅由于實(shí)現(xiàn)上造成的,其實(shí)還可以這樣避免:
            SetString(std::string str)
            {
            m_str = str.c_str();
            }
              回復(fù)  更多評(píng)論
              
            # re: std::string一個(gè)極其隱晦得問題
            2006-04-20 11:52 | cocalele
            SetString(std::string str) 雖然避免了問題,但對(duì)象的復(fù)制造成了效率下降。我喜歡

            <REF>
            2、將參與合作的module統(tǒng)統(tǒng)以multithreaded dll方式鏈入crt庫(kù),讓他們的“全局”數(shù)據(jù)真正全局,注意,所有有交互的module都需要?jiǎng)討B(tài)鏈入crt,
            </REF>
            而且為了避免這種內(nèi)存問題,我還自己做了一個(gè)內(nèi)存回收的實(shí)現(xiàn),所有模塊只分配內(nèi)存就行了  回復(fù)  更多評(píng)論
              
            # re: std::string一個(gè)極其隱晦得問題
            2006-04-20 19:53 | Squirrel
            那么,使用這樣不是更好?
            SetString( const std::string & str ){
            m_str = str;
            }  回復(fù)  更多評(píng)論
              
            # re: std::string一個(gè)極其隱晦得問題
            2006-04-20 22:17 | 萬連文
            SetString( const std::string & str ){
            m_str = str;
            }
            這樣不可以,因?yàn)檫@樣m_str引用str地址,假如導(dǎo)出類對(duì)象是成員變量m_expOBJ,
            有這樣一段代碼:
            str = "wlw";
            m_expOBJ.SetString(str);
            m_expOBJ的m_str引用str指針,作用域過去后str析構(gòu),此時(shí)由于指針被引用,沒有delete內(nèi)存,而m_expOBJ析構(gòu)的時(shí)候,m_str對(duì)象內(nèi)部指針沒有被引用,刪除時(shí)恰好發(fā)現(xiàn)指針不合法,引起問題。
            m_str = str.c_str();可以避免引用。   回復(fù)  更多評(píng)論
              
            # re: std::string一個(gè)極其隱晦得問題
            2006-07-26 15:51 | 愛上小白

            有一個(gè)不成文但是卻是重要的前提, STL對(duì)象盡量不要作為dll的接口傳遞.

            不過你說的問題應(yīng)該是不存在的, 因?yàn)?
            SetString(std::string str)
            {
            m_str = str; //這里++ref
            }

            所以結(jié)果str還是存在一個(gè)ref供外部調(diào)用的.
              回復(fù)  更多評(píng)論
              
            # re: std::string一個(gè)極其隱晦得問題
            2008-06-12 10:45 | 小潘
            我這幾天也遇到這個(gè)問題,此問對(duì)我有很多幫助,非常感謝,發(fā)現(xiàn)用STL對(duì)象的確有很多問題,最好改用const char * 如果需要然后在進(jìn)行轉(zhuǎn)換。  回復(fù)  更多評(píng)論
              
            # re: std::string一個(gè)極其隱晦得問題
            2011-07-30 07:48 | hls
            不是stl本身有問題,而是stl的微軟實(shí)現(xiàn)有問題,如果都用stlport就可以解決問題,因?yàn)槲④浥袛嘁粋€(gè)字符串是否沒有分配內(nèi)存不是拿指針是否為NULL來比較,而是把它和一個(gè)全局的“null”字符串來比較,這樣由于跨module后,出現(xiàn)了兩個(gè)“null”字符串,所以導(dǎo)致錯(cuò)誤。微軟的實(shí)現(xiàn)比較的垃圾。  回復(fù)  更多評(píng)論
              
            簡(jiǎn)歷下載
            聯(lián)系我

            <2007年6月>
            272829303112
            3456789
            10111213141516
            17181920212223
            24252627282930
            1234567

            常用鏈接

            留言簿(66)

            隨筆分類

            隨筆檔案

            相冊(cè)

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            伊人久久大香线蕉综合5g| 久久精品国产亚洲麻豆| 日韩精品久久久肉伦网站 | 国产成年无码久久久久毛片| 国产午夜精品久久久久九九电影 | 精品国产综合区久久久久久 | 久久人人爽人人爽人人片AV不| 久久精品国产网红主播| 日韩AV无码久久一区二区| 91精品日韩人妻无码久久不卡 | 久久人妻AV中文字幕| 一本久久精品一区二区| 97精品久久天干天天天按摩| 久久精品9988| 色综合久久久久久久久五月| 欧美牲交A欧牲交aⅴ久久| 久久精品国产亚洲一区二区三区| 久久久久久噜噜精品免费直播| 国产精品美女久久久m| 亚洲欧美成人久久综合中文网 | 久久精品夜夜夜夜夜久久| 中文字幕精品无码久久久久久3D日动漫| 久久久久亚洲精品无码蜜桃| 久久久精品久久久久影院| 久久久噜噜噜久久中文福利| 国产精品久久久久久久久久影院 | 色婷婷久久久SWAG精品| 性欧美大战久久久久久久| 久久久久国产一级毛片高清版| 国产毛片久久久久久国产毛片| 亚洲国产成人乱码精品女人久久久不卡| 国产精品对白刺激久久久| 国产激情久久久久久熟女老人| 69国产成人综合久久精品| 国产aⅴ激情无码久久| 久久久久久久久久久精品尤物| 日韩亚洲国产综合久久久| 亚洲国产精品嫩草影院久久| 久久精品国产国产精品四凭 | 国产成年无码久久久免费| 一本久道久久综合狠狠躁AV|