精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

我擼了個內存泄漏檢測工具,只用了兩招

開發 開發工具
不管使用什么語言,一定要處理好內存問題,要有檢測內存問題的方法論,于是擼了個檢測是否有泄漏的小工具,這里分享一波。

 [[389657]]

本文轉載自微信公眾號「程序喵大人」,作者程序喵大人。轉載本文請聯系程序喵大人公眾號。

大家看我寫了這么長時間C++文章,殊不知我在工作中已經一年多沒有用過C++了,最近做一個新項目,終于又回到C++的懷抱了,有點激動,也有點不適應。

不管使用什么語言,一定要處理好內存問題,要有檢測內存問題的方法論,于是擼了個檢測是否有泄漏的小工具,這里分享一波。

先貼個效果圖:

實現方法

眾所周知C++中申請和釋放內存使用的是new和delete關鍵字:

  1. void func() { 
  2.     A* a = new A(); 
  3.     delete a; 
  4.     A* b = new int[4]; 
  5.     delete[] b; 

再明確下需求:如果程序中存在內存泄漏,我們的目的是找到這些內存是在哪里分配的,如果能夠具體對應到代碼中哪一個文件的那一行代碼最好。好了需求明確了,開始實現。

內存在哪里釋放的我們沒必要監測,只需要檢測出內存是在哪里申請的即可,如何檢測呢?

整體思路很簡單:在申請內存時記錄下該內存的地址和在代碼中申請內存的位置,在內存銷毀時刪除該地址對應的記錄,程序最后統計下還有哪條記錄沒有被刪除,如果還有沒被刪除的記錄就代表有內存泄漏。

很多人應該都知道new關鍵字更底層是通過operator new來申請內存的:

  1. void* operator new(std::size_t sz) 

也就是正常情況下C++都是通過operator new(std::size_t sz)來申請內存,而這個操作符我們可以重載:

  1. void* operator new(std::size_t size, const char* file, int line); 
  2. void* operator new[](std::size_t size, const char* file, int line); 

tip:new和new[]的區別我就不具體介紹了,太基礎。

如果能讓程序申請內存時調用重載的這個函數,就可以記錄下內存申請的具體位置啦。

怎么能夠讓底層程序申請內存時調用重載的這個函數呢?這里可以對new使用宏定義:

  1. #define new new (__FILE__, __LINE__) 

有了這個宏定義后,在new A的時候底層就會自動調用operator new(std::size_t size, const char* file, int line)函數,至此達到了我們記錄內存申請位置的目的。

這里有兩個問題:

  1. 在哪里記錄內存申請的位置等信息呢?如果在operator new內部又申請了一塊內存,用于記錄位置,那新申請的這塊內存需要記錄不?這豈不是遞歸調用了?
  2. 只有在new宏定義包裹范圍內申請了內存才會被記錄,然而某些第三方庫或者某些地方沒有被new宏定義包裹,可能就無法被監測是否申請了內存吧?

下面逐個擊破:

哪里存儲具體信息?

我們肯定不能讓它遞歸調用啊,那這些信息存儲在哪里呢?這里可以在每次申請內存時,一次性申請一塊稍微大點的內存,具體信息存儲在多余的那塊內存里,像這樣:

  1. static void* alloc_mem(std::size_t size, const char* file, int line, bool is_array) { 
  2.     assert(line >= 0); 
  3.  
  4.     std::size_t s = size + ALIGNED_LIST_ITEM_SIZE; 
  5.     new_ptr_list_t* ptr = (new_ptr_list_t*)malloc(s); 
  6.     if (ptr == nullptr) { 
  7.         std::unique_lock<std::mutex> lock(new_output_lock); 
  8.         printf("Out of memory when allocating %lu bytes\n", (unsigned long)size); 
  9.         abort(); 
  10.     } 
  11.     void* usr_ptr = (char*)ptr + ALIGNED_LIST_ITEM_SIZE; 
  12.  
  13.     if (line) { 
  14.         strncpy(ptr->file, file, _DEBUG_NEW_FILENAME_LEN - 1)[_DEBUG_NEW_FILENAME_LEN - 1] = '\0'
  15.     } else { 
  16.         ptr->addr = (void*)file; 
  17.     } 
  18.  
  19.     ptr->line = line; 
  20.     ptr->is_array = is_array; 
  21.     ptr->size = size
  22.     ptr->magic = DEBUG_NEW_MAGIC; 
  23.     { 
  24.         std::unique_lock<std::mutex> lock(new_ptr_lock); 
  25.         ptr->prev = new_ptr_list.prev; 
  26.         ptr->next = &new_ptr_list; 
  27.         new_ptr_list.prev->next = ptr; 
  28.         new_ptr_list.prev = ptr; 
  29.     } 
  30.     total_mem_alloc += size
  31.     return usr_ptr; 

new_ptr_list_t結構體定義如下:

  1. struct new_ptr_list_t { 
  2.     new_ptr_list_t* next
  3.     new_ptr_list_t* prev; 
  4.     std::size_t size
  5.     union { 
  6.         char file[200]; 
  7.  
  8.         void* addr; 
  9.     }; 
  10.     unsigned line; 
  11. }; 

沒有被new宏包裹的地方可以檢測的到嗎?

沒有被new宏包裹的地方是會調用operator new(std::size_t sz)函數來申請內存的。這里operator new函數不只可以重載,還可以重新定義它的實現,而且不會報multi definition的錯誤哦。因為它是一個weak symbol,有關strong symbol和weak symbol的知識點可以看我之前的一篇文章:《談談程序鏈接及分段那些事》

既然可以重定義,那就可以這樣:

  1. void* operator new(std::size_t size) {  
  2.     return operator new(size, nullptr, 0);  

這樣有個缺點,就是不能記錄內存申請的具體代碼位置,只能記錄下來是否申請過內存,不過這也挺好,怎么也比沒有任何感知強的多。

其實這里不是沒有辦法,盡管沒有了new宏,獲取不到具體申請內存的代碼位置,但是可以獲取到調用棧信息,把調用棧信息存儲起來,還是可以定位大體位置。關于如何獲取調用棧信息,大家可以研究下libunwind庫看看。

釋放內存時怎么辦?

這里需要重定義operator delete(void* ptr)函數:

  1. void operator delete(void* ptr) noexcept {  
  2.     free_pointer(ptr, nullptr, false);  

free_pointer函數的大體思路就是在鏈表中找到要對應節點,刪除掉,具體定義如下:

  1. static void free_pointer(void* usr_ptr, void* addr, bool is_array) { 
  2.     if (usr_ptr == nullptr) { 
  3.         return
  4.     } 
  5.     new_ptr_list_t* ptr = (new_ptr_list_t*)((char*)usr_ptr - ALIGNED_LIST_ITEM_SIZE); 
  6.     { 
  7.         std::unique_lock<std::mutex> lock(new_ptr_lock); 
  8.         total_mem_alloc -= ptr->size
  9.         ptr->magic = 0; 
  10.         ptr->prev->next = ptr->next
  11.         ptr->next->prev = ptr->prev; 
  12.     } 
  13.     free(ptr); 

如何檢測是否有內存泄漏?

遍歷鏈表即可,每次new時候會把這段內存插入鏈表,delete時候會把這段內存從鏈表中移出,如果程序最后鏈表長度不為0,即為有內存泄漏,代碼如下:

  1. int checkLeaks() { 
  2.     int leak_cnt = 0; 
  3.     int whitelisted_leak_cnt = 0; 
  4.     new_ptr_list_t* ptr = new_ptr_list.next
  5.  
  6.     while (ptr != &new_ptr_list) { 
  7.         const char* const usr_ptr = (char*)ptr + ALIGNED_LIST_ITEM_SIZE; 
  8.         printf("Leaked object at %p (size %lu, ", usr_ptr, (unsigned long)ptr->size); 
  9.         if (ptr->line != 0) { 
  10.             print_position(ptr->file, ptr->line); 
  11.         } else { 
  12.             print_position(ptr->addr, ptr->line); 
  13.         } 
  14.         printf(")\n"); 
  15.         ptr = ptr->next
  16.         ++leak_cnt; 
  17.     } 
  18.     return leak_cnt; 

ps:關于可以重定義operator new這個操作,我也是最近看到別人代碼后才發現,于是參考別人代碼小擼了個代碼檢測工具,希望大家有所收獲!

 

責任編輯:武曉燕 來源: 程序喵大人
相關推薦

2021-11-05 08:29:13

數據校驗Spring

2017-05-24 17:25:44

2025-06-03 17:37:49

模型訓練AI

2025-04-08 00:33:00

數據校驗Bean

2024-07-03 11:28:15

2019-09-09 11:35:21

GitHub工具瀏覽

2013-08-02 09:52:14

AndroidApp內存泄漏

2021-12-23 11:10:38

稅收大數據大數據稅收

2017-09-07 16:52:23

2020-11-04 07:56:19

工具Linux 翻譯

2015-04-17 10:35:51

c++c++程序內存泄漏檢測代碼

2020-03-06 08:15:54

新人技術主管陳琦

2016-09-12 16:01:28

Android內存泄露內存管理

2011-08-15 10:16:55

內存泄露

2009-02-01 09:42:00

2009-11-20 10:55:13

Oracle數據比較

2023-07-17 07:06:51

電腦管家C盤文件

2024-04-19 15:55:01

系統設計繪圖工具

2024-04-19 08:00:00

2009-03-02 09:05:37

點贊
收藏

51CTO技術棧公眾號

四虎国产精品免费| 一区二区三区四区| 成年人av网站| 91精品啪在线观看国产18| 日韩一卡二卡三卡四卡| 91好吊色国产欧美日韩在线| 国产天堂在线| 国产成人在线看| 国产66精品| 国产亚洲自拍一区| 亚洲a级在线观看| 久久久国产高清| 国产精品特级毛片一区二区三区| 欧美有码在线| 欧美三级中文字幕| 老太脱裤子让老头玩xxxxx| 第一福利在线| 成人久久视频在线观看| 国产精品一区久久| 免费在线不卡视频| 亚洲欧洲美洲一区二区三区| 亚洲国产婷婷香蕉久久久久久| 天天插天天操天天射| a在线视频v视频| 国产精品福利一区| 久久综合九色欧美狠狠| 精品久久久久中文慕人妻 | 精品亚洲夜色av98在线观看 | www.国产成人| 夜间精品视频| 在线播放日韩专区| 在线观看国产网站| 亚洲啊v在线免费视频| 欧美日本一区二区在线观看| 成人在线看视频| a√中文在线观看| 一区二区成人在线视频| 天天做天天爱天天高潮| 成年人在线视频免费观看| 成av人片一区二区| 高清国产在线一区| www国产一区| 国产乱国产乱300精品| 国产精品综合网站| 在线观看中文字幕码| 久久综合婷婷| 日本欧美黄网站| 国产高清中文字幕| 久久精品一区| 国产成人av在线| 少妇久久久久久久| 三级精品在线观看| 国产精品精品视频| 国产在线一级片| 日本欧美一区二区三区| 国产成人涩涩涩视频在线观看| 黄网在线观看视频| 久久久成人网| 国产精品wwwwww| 中文字幕欧美色图| 六月丁香婷婷色狠狠久久| 国产精品香蕉在线观看| 国产精品成人久久久| 欧美aⅴ一区二区三区视频| 国产精品久久久久免费a∨| 中文天堂在线资源| 激情图片小说一区| 91gao视频| 狠狠综合久久av一区二区| 成人国产精品免费观看| 久久精品五月婷婷| jizz日韩| 亚洲精品国产精华液| av日韩在线看| 在线中文字幕播放| 欧美性生活一区| 爱豆国产剧免费观看大全剧苏畅 | 欧美精三区欧美精三区| 午夜诱惑痒痒网| 丁香5月婷婷久久| 亚洲毛片一区二区| 国产一二三四视频| 国产一区美女| 国产精品91久久久久久| 国产精品自偷自拍| av在线播放成人| 日韩免费三级| 手机在线免费观看av| 欧美日韩一二三四五区| 邪恶网站在线观看| 一区二区三区视频播放| 亚洲欧美日韩中文在线| 人人澡人人澡人人看| 亚洲国产高清一区二区三区| 热久久这里只有| 国产精品一区二区av白丝下载| 成人一级黄色片| 亚洲v国产v在线观看| 手机电影在线观看| 欧美性色aⅴ视频一区日韩精品| 亚洲午夜激情影院| 日韩av午夜| 久久综合伊人77777蜜臀| 五月天婷婷综合网| 久久精品国产精品亚洲红杏 | 6080国产精品| 日韩av三区| 欧美理论片在线观看| 亚洲精品中文字幕乱码三区91| 国产一区二区伦理片| 欧美成人在线免费观看| 蜜臀av在线| 欧美日韩一区不卡| 特大黑人巨人吊xxxx| 欧美一区二区| 成人a在线观看| 台湾av在线二三区观看| 亚洲精品一二三四区| 亚洲黄色a v| 欧美午夜18电影| 欧美福利小视频| 一区二区三区午夜| 国产视频911| 少妇人妻在线视频| 视频在线观看免费影院欧美meiju| 亚洲性日韩精品一区二区| 国产无套内射又大又猛又粗又爽| 国内久久精品视频| 天堂av一区二区| 成人做爰视频www网站小优视频| 精品国产凹凸成av人导航| 日韩av网站在线播放| 三级影片在线观看欧美日韩一区二区| 国产精品区免费视频| a毛片在线播放| 欧美美女直播网站| 日韩av毛片在线观看| 日韩电影在线免费观看| 免费在线观看91| 麻豆免费版在线观看| 亚洲精品99久久久久中文字幕| 免费在线观看国产精品| 国产剧情av麻豆香蕉精品| 亚洲精品国产精品久久| 123成人网| 亚洲午夜未删减在线观看| 五月天激情四射| 久久久美女毛片| 久久人妻精品白浆国产| 欧美禁忌电影网| 国产精品27p| 国产中文在线观看| 在线国产电影不卡| 国产欧美一区二区三区在线观看视频| 日精品一区二区| 天天爽天天狠久久久| 亚洲一二三四| 伊人久久久久久久久久久| a片在线免费观看| 国产精品欧美极品| 国产5g成人5g天天爽| 午夜久久tv| 国产伦精品一区二区三区视频黑人 | 亚洲欧洲精品一区二区| 91麻豆精品| 欧美久久久精品| 神马午夜一区二区| 色综合天天视频在线观看| 无码少妇精品一区二区免费动态| 免费久久精品视频| 91九色国产ts另类人妖| 超碰一区二区三区| 57pao国产精品一区| 国产天堂在线| 欧美一区二区三区在| 久久一区二区三| 久久免费视频色| 久久精品影视大全| 午夜视频精品| 免费成人在线观看av| 日韩一区二区三区免费| 久久亚洲一区二区三区四区五区高 | 亚洲变态欧美另类捆绑| 成年人视频在线免费看| 中文av一区二区| 黄页网站在线看| 亚洲综合欧美| 国产高清精品软男同| 日韩av不卡一区| 国产中文字幕日韩| 美女扒开腿让男人桶爽久久软| 综合av色偷偷网| 丰满熟女一区二区三区| 色综合久久久久综合| 波多野结衣在线网址| 91美女蜜桃在线| 中文字幕22页| 国产亚洲网站| 国产对白在线播放| 亚洲v天堂v手机在线| 91在线免费观看网站| 黑人巨大精品| 欧美高清视频一区二区| 久久精品a一级国产免视看成人| 8v天堂国产在线一区二区| 国产精品视频免费播放| 亚洲乱码国产乱码精品精的特点 | 国产a久久精品一区二区三区| 亚洲中国色老太| 国产伦精品一区二区三区视频金莲| 久久久91精品国产| 蝌蚪视频在线播放| 精品成人在线观看| 一级片视频免费| 欧美专区日韩专区| 亚洲另类欧美日韩| 亚洲国产人成综合网站| 日本午夜在线观看| 国产亚洲欧美日韩日本| 亚洲精品乱码久久久久久久| 国产毛片精品一区| 亚洲第一天堂久久| 奇米888四色在线精品| 国内外成人激情视频| 国产综合欧美| 超碰超碰超碰超碰超碰| 久久免费av| 日韩欧美第二区在线观看| 欧洲亚洲成人| 国内精品久久国产| 波多野结衣欧美| 97神马电影| 亚洲精品国产九九九| 亚洲精品欧美日韩| 国产精品3区| 91精品在线一区| 四虎影视国产精品| 成人国产精品一区二区| 国产精品.xx视频.xxtv| 国产精品久久久91| 蜜桃精品在线| 国产97在线|亚洲| 欧美激情喷水| 国产精品av电影| 成人在线免费av| 国产精品一区二区久久久| 99九九久久| 国产拍精品一二三| 国产精品天堂蜜av在线播放| 国产精品日韩在线观看| 国产亚洲人成a在线v网站| 国产日韩欧美日韩| 亚洲青青一区| 2014亚洲精品| 国产精品tv| 久久综合久久久| 欧洲福利电影| 一区二区三区三区在线| 在线精品国产| 国产a级片网站| 午夜在线观看免费一区| 黄色成人免费看| 精品一区二区三区视频| 国产探花一区二区三区| 成人国产亚洲欧美成人综合网| 艳妇乳肉亭妇荡乳av| 久久亚洲二区三区| 少妇愉情理伦三级| 亚洲色图欧美偷拍| 久热这里只有精品在线| 精品国产91久久久久久| 波多野结衣日韩| 91精品国产综合久久蜜臀 | 国产亚洲欧美视频| 精品美女在线观看视频在线观看 | 成人动漫视频在线观看| 国产精品我不卡| 欧美人妖在线| 一二三在线视频| 中日韩视频在线观看| 日韩欧美在线免费观看视频| 久久精品国产精品亚洲精品| 国产成人av片| 久久久亚洲高清| 国语对白在线播放| 欧美午夜宅男影院在线观看| 在线视频免费观看一区| 亚洲电影第1页| 成人精品一区二区| 欧美日韩不卡合集视频| 波多视频一区| 91九色蝌蚪嫩草| 国产一区二区三区日韩精品| 91xxx视频| 久久亚洲欧美| 女人扒开腿免费视频app| 久久久亚洲高清| 久久久久久久极品内射| 欧美色倩网站大全免费| 天天干天天摸天天操| 久久综合免费视频| abab456成人免费网址| 国产精品对白刺激久久久| 欧美日韩精品在线一区| 毛片av在线播放| 日韩高清一区二区| 无码精品一区二区三区在线播放 | 亚洲欧洲第一视频| 国内在线免费视频| 成人免费午夜电影| 欧美禁忌电影网| 国产91在线视频观看| 国产成人三级在线观看| 国产一区二区三区四区在线| 黄色精品一区二区| www.久久成人| 久久手机精品视频| 成人影院在线免费观看| 欧美久久在线| 国产欧美精品久久| 蜜臀av粉嫩av懂色av| 亚洲视频1区2区| 伊人亚洲综合网| 亚洲欧美国产一区二区三区| av小说在线播放| 99在线国产| 欧美在线影院| 色婷婷激情视频| 国产精品成人免费精品自在线观看| 精品成人无码久久久久久| 亚洲第一二三四五区| heyzo高清国产精品| 99久久一区三区四区免费| 久久精品国内一区二区三区水蜜桃| 亚洲国产精品毛片av不卡在线| 99re8在线精品视频免费播放| 国产亚洲第一页| 日韩精品中文字幕在线不卡尤物 | 夜夜嗨av一区二区三区中文字幕| 一本色道久久综合亚洲| 日韩在线观看视频免费| 91精品国产66| 亚洲巨乳在线观看| 美国十次了思思久久精品导航| 我不卡一区二区| 在线视频你懂得一区二区三区| 欧美色视频免费| 国产97在线|亚洲| 成人免费看片39| 最新天堂中文在线| 一区二区中文字幕在线| 国产又粗又猛又爽又黄91| 搡老女人一区二区三区视频tv| 国产一区二区三区四区五区3d| 亚洲春色在线| 国产最新精品免费| 丰满少妇被猛烈进入一区二区| 欧美一区二区免费观在线| 毛片大全在线观看| 久久国产精品免费一区| 日日夜夜精品免费视频| 99久久精品久久亚洲精品| 欧美一区二区视频在线观看| 天堂av在线电影| 免费看污久久久| 久久国产精品色婷婷| 麻豆视频在线观看| 日韩的一区二区| 黄色日韩网站| 免费高清一区二区三区| 久久综合狠狠综合久久综合88 | 久久精品久久精品久久| 日韩电影在线观看中文字幕| 户外露出一区二区三区| 椎名由奈jux491在线播放| 国产成人免费视频网站| 亚洲高清毛片一区二区| 一区二区三区在线播放欧美| 亚洲日本中文| 少妇高潮喷水在线观看| 亚洲国产成人一区二区三区| 精品人妻午夜一区二区三区四区 | 蜜月aⅴ免费一区二区三区 | 日本国产一区| 国产精品三级一区二区| 26uuu精品一区二区在线观看| 中文字幕男人天堂| 欧美激情精品在线| 国产精品片aa在线观看| 精品人妻一区二区三| 欧美日韩在线一区| av免费网站在线| 久久综合色一本| 国产精品99久久久久久似苏梦涵| 亚洲久久在线观看| 欧美精品午夜视频| 国内成人精品| 看全色黄大色黄女片18| 欧美日本在线观看| 波多视频一区|