• <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>

            兔子的技術(shù)博客

            兔子

               :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
              202 Posts :: 0 Stories :: 43 Comments :: 0 Trackbacks

            留言簿(10)

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            慎用USES_CONVERSION

            USES_CONVERSION是ATL中的一個(gè)宏定義。用于編碼轉(zhuǎn)換(用的比較多的是CString向LPCWSTR轉(zhuǎn)換)。在ATL下使用要包含頭文件#include "atlconv.h"

            使用USES_CONVERSION一定要小心,它們從堆棧上分配內(nèi)存,直到調(diào)用它的函數(shù)返回,該內(nèi)存不會(huì)被釋放。如果在一個(gè)循環(huán)中,這個(gè)宏被反復(fù)調(diào)用幾萬(wàn)次,將不可避免的產(chǎn)生stackoverflow。

             

            在一個(gè)函數(shù)的循環(huán)體中使用A2W等字符轉(zhuǎn)換宏可能引起棧溢出。

            #include <atlconv.h>
            void fn()
            {
                
            while(true)
                {
                    {
                        USES_CONVERSION;
                        DoSomething(A2W(
            "SomeString"));
                    }
                }
            }

            讓我們來(lái)分析以上的轉(zhuǎn)換宏

            #define A2W(lpa) (\
               ((_lpa 
            = lpa) == NULL) ? NULL : (\
                  _convert 
            = (lstrlenA(_lpa)+1),\
                  ATLA2WHELPER((LPWSTR) alloca(_convert
            *2), _lpa, _convert)))
            #define ATLA2WHELPER AtlA2WHelper
            inline LPWSTR WINAPI AtlA2WHelper(LPWSTR lpw, LPCSTR lpa, 
            int nChars, UINT acp)
            {
               ATLASSERT(lpa 
            != NULL);
               ATLASSERT(lpw 
            != NULL);
               
            // verify that no illegal character present
               
            // since lpw was allocated based on the size of lpa
               
            // don't worry about the number of chars
               lpw[0= '\0';
               MultiByteToWideChar(acp, 
            0, lpa, -1, lpw, nChars);
               
            return lpw;
            }

            關(guān)鍵的地方在 alloca  內(nèi)存分配內(nèi)存上。

            #define alloca  _alloca

            _alloca
            Allocates memory on the stack.

            Remarks
            _alloca allocates size bytes from the program stack. The allocated space is automatically freed when the calling function

            exits. Therefore, do not pass the pointer value returned by _alloca as an argument to free.

            問(wèn)題就在這里,分配的內(nèi)存是在函數(shù)的棧中分配的。而VC編譯器默認(rèn)的棧內(nèi)存空間是2M。當(dāng)在一個(gè)函數(shù)中循環(huán)調(diào)用它時(shí)就會(huì)不斷的分配棧中的內(nèi)存。

            以上問(wèn)題的解決辦法:
            1、自己寫字符轉(zhuǎn)換函數(shù),不要偷懶

            Function that safely converts a 'WCHAR' String to 'LPSTR':
            char* ConvertLPWSTRToLPSTR (LPWSTR lpwszStrIn)
            {
              LPSTR pszOut 
            = NULL;
              
            if (lpwszStrIn != NULL)
              {
             
            int nInputStrLen = wcslen (lpwszStrIn);
             
            // Double NULL Termination
             int nOutputStrLen = WideCharToMultiByte (CP_ACP, 0, lpwszStrIn, nInputStrLen, NULL, 000+ 2;
             pszOut 
            = new char [nOutputStrLen];
             
            if (pszOut)
             {
               memset (pszOut, 
            0x00, nOutputStrLen);
               WideCharToMultiByte(CP_ACP, 
            0, lpwszStrIn, nInputStrLen, pszOut, nOutputStrLen, 00);
             }
              }
              
            return pszOut;
            }

            等等一個(gè)一個(gè)的實(shí)現(xiàn)。

            2、把字符轉(zhuǎn)換部分放到一個(gè)函數(shù)中處理。

            void fn2()
            {
                USES_CONVERSION;
                DoSomething(A2W(
            "SomeString"));
            }
            void fn()
            {
                
            while(true)
                {
                    fn2();
                }
            }

            如果不知道這點(diǎn)問(wèn)題,在使用后崩潰時(shí)很難查出崩潰原因的。


            轉(zhuǎn)自:http://www.cnblogs.com/carekee/articles/1935789.html 

            posted on 2012-08-13 12:23 會(huì)飛的兔子 閱讀(569) 評(píng)論(0)  編輯 收藏 引用 所屬分類: C++及開(kāi)發(fā)環(huán)境
            精品久久久无码中文字幕| 亚洲国产精品久久久久婷婷老年| 99精品久久精品一区二区| 久久亚洲AV成人出白浆无码国产| 久久久久亚洲AV无码观看| 久久99精品久久久久婷婷| AAA级久久久精品无码片| 国产精品久久久久影院色| 久久国产亚洲精品麻豆| 久久激情五月丁香伊人| 久久有码中文字幕| 色婷婷综合久久久久中文| 久久精品水蜜桃av综合天堂| 久久精品国产男包| 99久久99久久久精品齐齐| 91亚洲国产成人久久精品网址| 国产精品伊人久久伊人电影| 7777精品久久久大香线蕉| 国产精品久久久久影视不卡| 色欲综合久久躁天天躁| 久久久久无码精品国产| 一本一道久久精品综合| 久久WWW免费人成一看片| 狠色狠色狠狠色综合久久| 伊人色综合九久久天天蜜桃| 久久精品麻豆日日躁夜夜躁| 久久99精品免费一区二区| 人妻久久久一区二区三区| 国产精品内射久久久久欢欢| 婷婷久久久亚洲欧洲日产国码AV| 九九久久99综合一区二区| 国产成人精品综合久久久久| 国产精品伦理久久久久久| 亚洲伊人久久成综合人影院 | 综合久久精品色| 久久国产精品成人片免费| 思思久久99热免费精品6| 青青草原综合久久大伊人精品| 久久精品一区二区三区AV| 亚洲欧美一区二区三区久久| 精品久久久久久无码国产|