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

            鍵盤的詠嘆調(diào)

            常用鏈接

            統(tǒng)計(jì)

            最新評(píng)論

            【zz】使用CRT調(diào)試內(nèi)存分配堆來找出未釋放的內(nèi)存空間

               原地址:http://blog.csdn.net/Donjuan/archive/2009/02/02/3859154.aspx

               忘記釋放已經(jīng)分配的內(nèi)存是一種常見的編程錯(cuò)誤,當(dāng)然我指的是在
            C++編程當(dāng)中,例如下面的代碼里面就存在一個(gè)忘記釋放內(nèi)存的編程錯(cuò)誤。我個(gè)人覺得忘記釋放內(nèi)存的編程錯(cuò)誤是不可避免的,畢竟程序員都是人,困了,心情不好了,代碼過于復(fù)雜啦等等都可能導(dǎo)致忘記加上一句delete XXX語句。

            // 未釋放內(nèi)存空間.cpp : Defines the entry point for the console application.

             

            #include "stdafx.h"

            #include <windows.h>

            #include <string>

            #include <iostream>

             

            using namespace std;

             

            class CTestClass

            {

            public:

                CTestClass(LPWSTR szName)

                {

                    m_lpName = new wstring(szName);

                }

             

                ~CTestClass()

                {

                }

             

                void PrintName()

                {

                    wcout << *m_lpName << endl;

                }

             

            private:

                wstring *m_lpName;

            };

             

            HRESULT CreateTestClass(LPWSTR szName, CTestClass **ppObject)

            {

                *ppObject = new CTestClass(szName);

                if ( (*ppObject) == NULL )

                    return E_FAIL;

                else

                    return S_OK;

            }

             

            int _tmain(int argc, _TCHAR* argv[])

            {

                CTestClass *pObject = NULL;

                HRESULT hr = CreateTestClass(L"This is a Test", &pObject);

                if ( hr != S_OK )

                {

                    return -1;

                }

                else

                {

                    pObject->PrintName();  // pObject沒有被釋放

                    return 0;

                }

            }

             

            實(shí)際上Visual Studio已經(jīng)提供了方法幫助你快速找到這些沒有釋放的內(nèi)存。

             

            Visual Studio提供了一系列的CRT調(diào)試APICRT提供了一個(gè)調(diào)試內(nèi)存分配堆,可以跟蹤和管理內(nèi)存在什么地方分配,當(dāng)你在這個(gè)堆上分配內(nèi)存的時(shí)候,每一次內(nèi)存分配調(diào)用例如malloc或者newCRT都會(huì)額外分配大約36個(gè)字節(jié)用來保存例如這個(gè)內(nèi)存塊分配的文件名、行號(hào)、內(nèi)存塊的大小等信息,最后CRT將這些內(nèi)存塊使用一個(gè)雙鏈表鏈接起來。每一次內(nèi)存釋放的時(shí)候,free或者delete函數(shù)就從這個(gè)內(nèi)存塊鏈表里面將要釋放的內(nèi)存塊刪除,因此在需要檢查內(nèi)存泄漏的時(shí)候,只要遍歷這個(gè)雙鏈表依次打印出這些內(nèi)存塊就可以發(fā)現(xiàn)所有未釋放的內(nèi)存了。下面是CRT內(nèi)存塊的原始聲明:

            typedef struct _CrtMemBlockHeader

            {

                // Pointer to the block allocated just before this one:

                struct _CrtMemBlockHeader *pBlockHeaderNext;

                // Pointer to the block allocated just after this one:

                struct _CrtMemBlockHeader *pBlockHeaderPrev;

                char *szFileName;    // File name

                int nLine;           // Line number

                size_t nDataSize;    // Size of user block

                int nBlockUse;       // Type of block

                long lRequest;       // Allocation number

                // Buffer just before (lower than) the user's memory:

                unsigned char gap[nNoMansLandSize];

            } _CrtMemBlockHeader;

             

            下面的代碼演示了如何使用CRT提供的調(diào)試API來修改剛才的源文件檢測未釋放的內(nèi)存空間(注意紅色添加的部分):

            // 未釋放內(nèi)存空間.cpp : Defines the entry point for the console application.

            //

             

            #include "stdafx.h"

            #include <windows.h>

            #include <string>

            #include <iostream>

            // 使用CRT調(diào)試API

            #include <crtdbg.h>

             

            using namespace std;

             

            // 將所有的內(nèi)存分配函數(shù)new替換成CRT提供的調(diào)試new

            #ifdef _DEBUG

            #   define DEBUG_CLIENTBLOCK new(_CLIENT_BLOCK, __FILE__, __LINE__)

            #else

            #   define DEBUG_CLIENTBLOCK

            #endif

             

            #ifdef _DEBUG

            #    define new DEBUG_CLIENTBLOCK

            #endif

             

            class CTestClass

            {

            public:

                CTestClass(LPWSTR szName)

                {

                    m_lpName = new wstring(szName);

                }

             

                ~CTestClass()

                {

                }

             

                void PrintName()

                {

                    wcout << *m_lpName << endl;

                }

             

            private:

                wstring *m_lpName;

            };

             

            HRESULT CreateTestClass(LPWSTR szName, CTestClass **ppObject)

            {

                *ppObject = new CTestClass(szName);

                if ( (*ppObject) == NULL )

                    return E_FAIL;

                else

                    return S_OK;

            }

             

            int _tmain(int argc, _TCHAR* argv[])

            {  

            // 設(shè)置CRT調(diào)試API的報(bào)表輸出模式,將所有的錯(cuò)誤、警告還有斷言都輸出到控制臺(tái)

                _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );

                _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );

                _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );

                _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );

                _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );

                _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );

             

                CTestClass *pObject = NULL;

                HRESULT hr = CreateTestClass(L"This is a Test", &pObject);

                if ( hr != S_OK )

                {

                    return -1;

                }

                else

                {

                    pObject->PrintName();

             

            // 檢查未釋放的內(nèi)存

                    _CrtDumpMemoryLeaks();

                    return 0;

                }

            }

            posted on 2009-02-03 11:59 鍵盤的詠嘆調(diào) 閱讀(417) 評(píng)論(0)  編輯 收藏 引用 所屬分類: C++

            97精品伊人久久大香线蕉| 国产精品久久久久影院嫩草| 久久91精品国产91久| 无码人妻精品一区二区三区久久| 蜜臀久久99精品久久久久久小说| 99国产精品久久久久久久成人热| 久久99精品久久久久久噜噜| 日本亚洲色大成网站WWW久久| 国产偷久久久精品专区| 久久亚洲欧美日本精品| 亚洲综合久久夜AV | 国产精品久久99| 亚洲七七久久精品中文国产| 国产精品无码久久综合| 久久夜色撩人精品国产| 99久久综合狠狠综合久久止| 久久久WWW免费人成精品| 久久精品无码专区免费青青 | 亚洲精品乱码久久久久久中文字幕| 久久婷婷五月综合97色| 久久这里有精品| 亚洲乱亚洲乱淫久久| 午夜人妻久久久久久久久| 亚洲国产香蕉人人爽成AV片久久 | 亚洲国产成人久久综合一| 亚洲国产精品狼友中文久久久 | 久久无码专区国产精品发布 | 久久久久久久精品成人热色戒| 日本道色综合久久影院| 久久综合亚洲欧美成人| 久久AV高潮AV无码AV| 要久久爱在线免费观看| 亚洲欧美国产精品专区久久| 亚洲精品成人久久久| 久久无码人妻精品一区二区三区| 国产精品综合久久第一页| 精品久久国产一区二区三区香蕉| 情人伊人久久综合亚洲| 久久精品中文字幕有码| 狠狠色丁香久久婷婷综合_中 | 久久国产V一级毛多内射|