<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      厚積薄發
      海納百川,有容乃大
      盡管這個概念已經讓人說濫了 ,還是想簡單記錄一下, 以備以后查詢。

      #ifdef _DEBUG
      #define DEBUG_CLIENTBLOCK   new( _CLIENT_BLOCK, __FILE__, __LINE__)
      #else
      #define DEBUG_CLIENTBLOCK
      #endif
      #define _CRTDBG_MAP_ALLOC
      #include <crtdbg.h>
      #ifdef _DEBUG
      #define new DEBUG_CLIENTBLOCK
      #endif


      int _tmain(int argc, _TCHAR* argv[])
      {
          char* p = new char();
          char* pp = new char[10];
          char* ppp = (char*)malloc(10);

          _CrtDumpMemoryLeaks();

          return 0;
      }

      主要原理是運用Crt 的內存調試功能, 通過宏替代默認的operator new, 讓它被下面版本替代:
      void *__CRTDECL operator new(
              size_t cb,
              int nBlockUse,
              const char * szFileName,
              int nLine
              )
              _THROW1(_STD bad_alloc)
      {
          /* _nh_malloc_dbg already calls _heap_alloc_dbg in a loop and calls _callnewh
             if the allocation fails. If _callnewh returns (very likely because no
             new handlers have been installed by the user), _nh_malloc_dbg returns NULL.
           
      */
          void *res = _nh_malloc_dbg( cb, 1, nBlockUse, szFileName, nLine );

          RTCCALLBACK(_RTC_Allocate_hook, (res, cb, 0));

          /* if the allocation fails, we throw std::bad_alloc */
          if (res == 0)
          {
              static const std::bad_alloc nomem;
              _RAISE(nomem);
          }

          return res;
      }
      這樣Crt會把此次分配內存的文件名和行號以及大小等記錄下來,最后當調用用_CrtDumpMemoryLeaks(); 時如果還沒釋放就會打印出來。
      結果如下:
      Detected memory leaks!
      Dumping objects ->
      f:\test\memleakchecker\memleakchecker\memleakchecker.cpp(23) : {108} normal block at 0x0003A1A8, 10 bytes long.
       Data: <          > CD CD CD CD CD CD CD CD CD CD 
      f:\test\memleakchecker\memleakchecker\memleakchecker.cpp(22) : {107} client block at 0x0003A160, subtype 0, 10 bytes long.
       Data: <          > CD CD CD CD CD CD CD CD CD CD 
      f:\test\memleakchecker\memleakchecker\memleakchecker.cpp(21) : {106} client block at 0x0003A120, subtype 0, 1 bytes long.
       Data: < > 00 
      Object dump complete.

      下面是一些注意事項:
      (1) #define _CRTDBG_MAP_ALLOC 的作用
      如果不定義這個宏, C方式的malloc泄露不會被記錄下來。

      (2)數字{108} {107}的作用
      表示第幾次分配, 你可以通過_CrtSetBreakAlloc程序運行到預定次數時暫停 ,比如
      int _tmain(int argc, _TCHAR* argv[])
      {
          _CrtSetBreakAlloc(108);

          char* p = new char();
          char* pp = new char[10];
          char* ppp = (char*)malloc(10);

          _CrtDumpMemoryLeaks();

          return 0;
      }

      (3)如果程序有多個出口或是有涉及到全局變量, 可以通過_CrtSetDbgFlag 設置標志讓程序退出時自動打印泄露 , 比如
      int _tmain(int argc, _TCHAR* argv[])
      {
          _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

          char* p = new char();
          char* pp = new char[10];
          char* ppp = (char*)malloc(10);

          return 0;
      }

      (4)我們知道宏替代是最粗暴的方式, 所以盡量把下面new的替代宏放到每個Cpp里而不是放到一個通用的頭文件中, 實際上MFC也是這么做的
      #ifdef _DEBUG
      #define new DEBUG_CLIENTBLOCK
      #endif

      (5)上面的operator new只能照顧到最普通的new, 實際上operator new是有任意多種重載方式, 只需要確保第一個參數是表示大小。 比如下面的placement new就會編譯失敗, 因為宏替代后格式不符合要求了, 所以如果你的CPP用了非標準的new, 就不要加入new的檢測宏了。
      #include <new>

      #ifdef _DEBUG
      #define DEBUG_CLIENTBLOCK   new( _CLIENT_BLOCK, __FILE__, __LINE__)
      #else
      #define DEBUG_CLIENTBLOCK
      #endif
      #define _CRTDBG_MAP_ALLOC
      #include <crtdbg.h>
      #ifdef _DEBUG
      #define new DEBUG_CLIENTBLOCK
      #endif


      int _tmain(int argc, _TCHAR* argv[])
      {
          _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

          char* p = new char();
          char* pp = new char[10];
          char* ppp = (char*)malloc(10);

          char d;
          char* p1 = new(&d) char('a');

          return 0;
      }

      (6)因為STL里map內的tree用到了placement new,  所以如果你這樣用會編譯失?。?/span>
      #ifdef _DEBUG
      #define DEBUG_CLIENTBLOCK   new( _CLIENT_BLOCK, __FILE__, __LINE__)
      #else
      #define DEBUG_CLIENTBLOCK
      #endif
      #define _CRTDBG_MAP_ALLOC
      #include <crtdbg.h>
      #ifdef _DEBUG
      #define new DEBUG_CLIENTBLOCK
      #endif

      #include <map>
      你應該把 #include <map>放到 宏定義的前面。

      (7) 如果你在宏 #define new DEBUG_CLIENTBLOCK 之后再聲明或定義 operator new函數, 都會因為宏替代而編譯失敗。
      而STL的xdebug文件恰恰申明了operator new函數, 所以請確保new的替代宏放在所有include頭文件的最后, 尤其要放在STL頭文件的后面。
      //MyClass.cpp
      #include "myclass.h"
      #include <map>
      #include <algorithm>

      #ifdef _DEBUG
      #define new DEBUG_CLIENTBLOCK
      #endif

      MyClass::MyClass()
      {
          char* p = new char('a');
      }

      (8)如果你覺得上面的這種new替代宏分散在各個CPP里太麻煩, 想把所有的東西放到一個通用頭文件里,請參考下面定義的方式:
      //MemLeakChecker.h 
      #include <map>
      #include <algorithm>
      //other STL file

      #ifdef _DEBUG
      #define DEBUG_CLIENTBLOCK   new( _CLIENT_BLOCK, __FILE__, __LINE__)
      #else
      #define DEBUG_CLIENTBLOCK
      #endif
      #define _CRTDBG_MAP_ALLOC
      #include <crtdbg.h>
      #ifdef _DEBUG
      #define new DEBUG_CLIENTBLOCK
      #endif
       
      (9)簡單判斷某個獨立函數有沒有內存泄露可以用下面的方法:
      class DbgMemLeak
      {
          _CrtMemState m_checkpoint;

      public:
          explicit DbgMemLeak() 
          {   
              _CrtMemCheckpoint(&m_checkpoint); 
          };

          ~DbgMemLeak()
          {
              _CrtMemState checkpoint;
              _CrtMemCheckpoint(&checkpoint);
              _CrtMemState diff;
              _CrtMemDifference(&diff, &m_checkpoint, &checkpoint);
              _CrtMemDumpStatistics(&diff);
              _CrtMemDumpAllObjectsSince(&diff);
          };
      };


      int _tmain(int argc, _TCHAR* argv[])
      {
          DbgMemLeak check;
          {
              char* p = new char();
              char* pp = new char[10];
              char* ppp = (char*)malloc(10);
          }

          return 0;
      }

       

       (10) 其實知道了原理, 自己寫一套C++內存泄露檢測也不難, 主要是重載operator new和operator delete, 可以把每次內存分配情況都記錄在一個Map里, delete時刪除記錄, 最后程序退出時把map里沒有delete的打印出來。 當然我們知道Crt在實現new時一般實際上調的是malloc, 而malloc可能又是調HeapAlloc,而HeapAlloc可能又是調用RtlAllocateHeap, 所以理論上我們可以在這些函數的任意一層攔截和記錄。但是如果你要實現自己的跨平臺內存泄露檢測,還是重載operator new吧。

       

      posted on 2013-02-25 22:33  Richard Wei  閱讀(1940)  評論(1)    收藏  舉報

      主站蜘蛛池模板: 自拍偷在线精品自拍偷99| 久久不见久久见免费视频观看| 欧美精品国产一区二区三区| 涞源县| 精品一区二区三区四区色| 婷婷色香五月综合缴缴情香蕉 | 国产精品久久露脸蜜臀| 国产精品无码一区二区在线| 国产丰满乱子伦午夜福利| 麻豆国产va免费精品高清在线| 黑人巨大精品欧美一区二区| 九九热爱视频精品视频| 国产又爽又黄的激情视频| 免费看婬乱a欧美大片| 免费观看欧美猛交视频黑人| 久久人人爽爽人人爽人人片av| 亚洲综合无码明星蕉在线视频| 兰西县| 国产女同一区二区在线| 亚洲国产福利成人一区二区| 国产白丝无码免费视频| 国产偷拍自拍视频在线观看| 18禁成人免费无码网站| 国产又色又爽又高潮免费| 好吊视频在线一区二区三区| 久久久久久综合网天天| 国产v亚洲v天堂无码久久久| 无码人妻少妇色欲av一区二区| 亚洲色婷婷综合开心网| 亚洲色大成网站www久久九九| 亚洲精品乱码久久久久久蜜桃图片 | 青青草原国产精品啪啪视频| 亚洲av色图一区二区三区| 国产在线观看黄| 亚洲情A成黄在线观看动漫尤物| 亚洲偷偷自拍码高清视频| 人妻有码中文字幕在线| 色欲狠狠躁天天躁无码中文字幕| 亚洲一区二区三区人妻天堂| 疯狂三人交性欧美| 98精品全国免费观看视频|