C 系列 44 C 記憶體洩露

2021-09-13 19:46:15 字數 2488 閱讀 6991

首先我們需要明確,記憶體洩露是記憶體丟了嗎?答案當然是否定的,不可能買了8g的記憶體執行程式之後變成了2g。記憶體是不會像物理意義上的丟失的,丟的只是指向這一片區域的指標。記憶體洩漏指因為疏忽或錯誤造成程式未能釋放已經不再使用的記憶體的情況。記憶體洩漏並不是指內存在物理上的消失,而是應用程式分配某段記憶體後,因為設計錯誤,失去了對該段記憶體的控制,因而造成了記憶體的浪費。

int main()
使用上來講有記憶體洩露,但程式結束後就將申請資源歸還給系統。對於該型別的記憶體洩露很好解決。

比如說:這個程式申請了1g,後面繼續申請了1g、1g...直至佔滿記憶體導致程式崩潰時,只需要將程式關閉或者重啟主機即可將記憶體自動**。類似於該型別的大片、大面積的記憶體洩露很好檢查,或者程式執行幾秒鐘就崩掉了。若不是系統、伺服器級的應用,該型別記憶體洩露危害不大。

而伺服器需要持續工作,24小時不能停機,有專人看護,製冷系統,甚至放入底下深層給其降溫,如果出現記憶體洩露導致伺服器崩潰是一件嚴重虧損事情。對於這種不停機的應用大片、大片的記憶體洩露也不可怕,因為很容易被發現並且可以及時對其處理。可怕的是不停機的應用卻有一小片一小片持續的記憶體洩露,很難被發現,有俗語:千里之堤毀於蟻穴,其像乙個定時炸彈,可能1年內都沒有問題,但是突然的某一天就引發伺服器宕機,背後造成的損失可能直接導致乙個公司從興直接轉衰。

int main()
如果有異常的話程式崩掉之後,記憶體不會被釋放,因為沒有執行下面的**,直接跳到catch或者其它地方,未執行delete,造成記憶體洩漏。這也是非常可怕的記憶體洩露!如果它也是不停機的應用,每次在這崩一下、catch一下,記憶體就洩露一點,也是一顆「定時炸彈」!

c/c++程式中一般我們關心兩種方面的記憶體洩漏:

1)堆記憶體洩漏(heap leak)

堆記憶體指的是程式執行中依據須要分配通過malloc / calloc / realloc / new等從堆中分配的一塊記憶體,用完後必須通過呼叫相應的 free或者delete 刪掉。假設程式的設計錯誤導致這部分記憶體沒有被釋放,那麼以後這部分空間將無法再被使用,就會產生heap leak。

2)系統資源洩漏

指程式使用系統分配的資源,比方套接字、檔案描述符、管道等沒有使用對應的函式釋放掉,導致系統資源的浪費,嚴重可導致系統效能減少,系統執行不穩定。

在linux下記憶體洩漏檢測:linux下幾款記憶體洩漏檢測工具

在windows下使用第三方工具:vld工具說明

其他工具:記憶體洩漏工具比較:記憶體洩漏工具比較

1)工程前期良好的設計規範,養成良好的編碼規範,申請的記憶體空間記著匹配的去釋放。ps:這個理想狀態。但是如果碰上異常時,就算注意釋放了,還是可能會出問題。需要下一條智慧型指標來管理才***。

2) 採用raii思想或者智慧型指標來管理資源。

3)有些公司內部規範使用內部實現的私有記憶體管理庫。這套庫自帶記憶體洩漏檢測的功能選項。

4)出問題了使用記憶體洩漏工具檢測。ps:不過很多任務具都不夠靠譜,或者收費昂貴。

總結一下:

記憶體洩漏非常常見,解決方案分為兩種:

1)事前預防型。如智慧型指標(主要思想為:raii,也稱為「資源獲取就是初始化」,是c++等程式語言常用的管理資源、避免記憶體洩露的方法。它保證在任何情況下,使用物件時先構造物件,最後析構物件)等。

2)事後查錯型。如洩漏檢測工具。

這也是一道面試題了,大多數同學的第一反應都是:不可能啊,怎麼能夠在堆上申請4g記憶體空間,我每次申請都告訴我編譯不通過啊,再說啊,程序的位址空間就4g,而且我的核心就佔1g,最多也只能申請3g啊,4g簡直不可能的好嗎???

其實每乙個程序都有乙個程序位址空間,每乙個程序都有乙個程序核心空間佔1g左右大小。假如說我的電腦上執行了這麼多程式,就有這麼多程序,每個程序都佔1g的話那我的電腦豈不是早就崩掉了?其實這些核心空間都指向同乙個空間,是乙個虛擬的 ,這個空間是不允許被使用的,每個程序都是這一段幫你使用。

我們之前編譯失敗原因是:我們編譯的程式都是x32,其中32位最大的定址空間或說最大的程序位址空間就是4g,並且核心還佔1g,所以肯定是申請不到的。然而在x64位下,就是4g*4g個大小的定址空間,每乙個程序都享用4g*4g的記憶體大小,但實際上並不能完全使用。

// 將程式編譯成x64的程序,執行下面的程式試試?

#include using namespace std;

int main()

修改編譯平台為x64位即可申請,並且與電腦是否為x64系統沒有任何關係,僅與編譯程式位數有關。申請出來的都是虛擬空間,編譯的位址都是虛擬位址,其真正與物理記憶體有乙個對映關係。有乙個頁表,可以將程式的虛擬位址對映到實體地址。不是說你有64g就全部對映為64g,而是一片一片的進行對映使用,但記憶體**昂貴,要不這樣做的話記憶體的利用率也不高。

44 C 基礎 容器介紹

容器分為 順序容器,關聯容器,容器適配類 是一種各個元素之間有順序關係的線性表 verctor 將元素保持在連續的儲存空間 deque list 雙鏈表,從任何地方快速插入與刪除 2.1 vector 相當於陣列,可以通過下標隨機訪問,速度很快。但是在容器的中間位置新增和刪除檔案非常耗時。因為一次插...

C 學習之路(44) C 大數問題

1.大數相加 1 從結尾開始每位相加 2 兩個整數長度不相等 肯定有乙個已經加完了,再把沒有加完的加上去 3 最高位有進製,要再進一位 4 結果字串逆序 2.大數相乘 分析 12 34 乘數 12 被乘數 34 1 先把乘數列出來,第i行列左起第i位數,列n次 n為乘數的位數 第二行起每次右移一位 ...

C 記憶體洩露

簡單點說就是只申請不釋放 在c 中我們通過malloc,new來通過系統申請記憶體,但當我們使用完畢之後 裡面可能就沒有執行相應的free和delete的操作,這樣我們申請的這部分記憶體系統就不會再次的 分配,這就造成了記憶體洩露!這篇帖子講的很細大家可以研究研究。我們在delete乙個指標之後要將...