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

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

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

            調試狀態下可以看到內部指針:
            s1=0x00364ff9
            s2=0x00365061
            然后執行

            s2? = ?s1;

            按下f11,進入xstring源文件:

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

            繼續進入assign(_X)函數:

            _Myt & ?assign( const ?_Myt & ?_X)
            ????????
            { return ?(assign(_X,? 0 ,?npos));?}???// 調用assign函數
            繼續進入assign函數,好戲都在這里面:
            _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()????????????????????????// 這個分支意思就是如果拷貝源有內容且就是就是源本身,并且
            ????????????
            &&?_Refcnt(_X.c_str())?<?_FROZEN?-?1??????????// 源字符串引用次數少于255-1次(可見引用次數最多255次),
            ????????????
            &&?allocator?==?_X.allocator)???????????????????????????//且源字符和目的字符分配器一致
            ????????????
            {_Tidy(true);?????????????????????????????????????????????// 刪除本身
            ????????????_Ptr?
            =?(_E?*)_X.c_str();????????????????????????????????????// 復制內容到目的串
            ????????????_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);?}

            這樣結果就是調用=號以后,s2地址和s1地址一樣,都是0x00364ff9。

            假如我們動態庫有這樣一個類class DLL接口:

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

            在客戶調用時候:

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

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

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

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

            解決問題的方法有:
            1、不要跨module傳遞c++對象,或者避免釋放跨module申請的內存

            2、將參與合作的module統統以multithreaded dll方式鏈入crt庫,讓他們的“全局”數據真正全局,注意,所有有交互的module都需要動態鏈入crt,

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

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

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

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

            所以結果str還是存在一個ref供外部調用的.
              回復  更多評論
              
            # re: std::string一個極其隱晦得問題
            2008-06-12 10:45 | 小潘
            我這幾天也遇到這個問題,此問對我有很多幫助,非常感謝,發現用STL對象的確有很多問題,最好改用const char * 如果需要然后在進行轉換。  回復  更多評論
              
            # re: std::string一個極其隱晦得問題
            2011-07-30 07:48 | hls
            不是stl本身有問題,而是stl的微軟實現有問題,如果都用stlport就可以解決問題,因為微軟判斷一個字符串是否沒有分配內存不是拿指針是否為NULL來比較,而是把它和一個全局的“null”字符串來比較,這樣由于跨module后,出現了兩個“null”字符串,所以導致錯誤。微軟的實現比較的垃圾。  回復  更多評論
              
            簡歷下載
            聯系我

            <2008年12月>
            30123456
            78910111213
            14151617181920
            21222324252627
            28293031123
            45678910

            常用鏈接

            留言簿(66)

            隨筆分類

            隨筆檔案

            相冊

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            国产综合成人久久大片91| 久久激情五月丁香伊人| 天堂久久天堂AV色综合| 91久久香蕉国产熟女线看| 久久影院综合精品| 久久亚洲精品国产亚洲老地址| 国产精品久久久久影院色| 中文无码久久精品| 2021国产精品久久精品| 久久精品二区| 久久国产精品无码一区二区三区 | 一本色综合久久| 久久精品成人免费国产片小草| 伊人久久无码中文字幕| 亚洲一区中文字幕久久| 久久久久亚洲AV无码麻豆| 亚洲国产成人久久综合野外| 久久91亚洲人成电影网站| 久久久久久久综合日本亚洲 | 97久久综合精品久久久综合| 无码人妻少妇久久中文字幕| 香港aa三级久久三级老师2021国产三级精品三级在| 久久毛片一区二区| 久久午夜福利电影| 久久中文字幕人妻丝袜| 色综合久久中文字幕综合网| 91精品国产91久久久久久蜜臀| 久久精品国产亚洲av水果派| 18岁日韩内射颜射午夜久久成人 | 中文字幕无码久久人妻| 国产精品免费久久久久影院| 久久精品国产福利国产琪琪| 久久99国产精一区二区三区| 99国产精品久久| 国产三级久久久精品麻豆三级| 国产成人久久777777| 欧美一区二区精品久久| 国产激情久久久久影院老熟女| 国产亚洲美女精品久久久| 国产三级观看久久| 色婷婷噜噜久久国产精品12p|