內存洩漏是指程序動態申請的內存在使用完後沒有釋放,導致這段內存不能被操作系統回收再利用。
例如這段程序,申請了4個字節的空間但沒有釋放,有4個字節的內存洩漏。
#include
using namespace std;
int main()
{
int *p = new int(1);
cout <<*p<
隨著時間的推移,洩漏的內存越來越多,可用的內存越來越少,輕則性能受損,重則系統崩潰。
一般情況下,發生內存洩漏時,重啟就可以回收洩漏的內存。但是對於linux,通常跑的是服務器程序,不可以隨意重啟,在內存洩漏問題上就要格外小心。
內存洩漏特點
難復現 — 要運行到足夠長的時間才會暴露。
難定位 — 出錯位置是隨機的,看不出與內存洩漏的代碼有什麼聯系。
最簡單的方法
為了避免寫出內存洩漏的程序,通常會有這樣的編程規范,要求我們在寫程序時申請和釋放成對出現的。因為每一次申請都意味著必須有一次釋放與它相對應。
基於這個特點,一種簡單的方法就是在代碼中統計申請和釋放的次數,如果申請和釋放的數量不同,就認為是內存洩漏了。
#include "stdio.h"
#include "stdlib.h"
int malloc_count, free_count;
void * my_malloc(int size)
{
malloc_count++;
return malloc(size);
}
void my_free(void *p)
{
free_count++;
free(p);
}
int main()
{
count = 0;
int *p1 = (int *)my_malloc(sizeif(int))
int *p2 = (int *)my_malloc(sizeif(int))
printf("%d, %d", p1, p2);
my_free(p1);
if(malloc_count != free_count)
printf("memory leak!\n");
return 0
}
方法分析
優點:
直觀,容易理解,容易實現
缺點:
1.該方法要求運行結束時對運行中產生的打印分析才能知道結果。
2.該方法要求封裝所有申請和釋放空間的函數,並在調用的地方修改成調用封裝後的函數。雖然C中申請/釋放內存接口並不多,但是對於一個大型的項目,調用這些接口的地方卻是很多的,要全部替換是一個比較大的工作量。
3.只對C語言適用,不能應用於C++
4.對於所調用的庫不適用。如果希望應用於庫,則要修改庫代碼
5.只能檢測是否洩漏,卻沒有具體信息,比如洩漏了多少空間
6.不能說明是哪一行代碼引起了洩漏
改進
這種方法雖然簡單的,卻有許多的不足,無法真正應用於項目中。欲知怎樣改進,且看下回分解。