當前位置:首頁 » 編程語言 » c語言內存檢測

c語言內存檢測

發布時間: 2022-08-11 08:56:57

⑴ vs編寫的c語言程序有辦法檢測用了多少內存嗎vc6.0也行。。

可以用GlobalMemoryStatus()函數實現,示例:


#include<stdio.h>
#include<Windows.h>

intmain(intargc,char*argv[])
{
MEMORYSTATUSmemStatus;
GlobalMemoryStatus(&memStatus);
printf("%lu ",memStatus.dwTotalPhys/1024/1024);//輸出系統內存的總量
printf("%lu ",memStatus.dwAvailPhys/1024/1024);//輸出系統內存的當前可用量
return0;
}

⑵ 高分求助!!!C內存泄露檢測問題

我的回答比較靠下,不知道你能不能看到呢?

是這樣的,你所給的Report是
1 free blocks
2 normal blocks
3 CRT blocks
4 ignore blocks
5 client blocks
6 maximum memory used by the program at any one time (in bytes)
7 total memory currently used by the program (in bytes)
以上內容來自MSDN,所以
Largest number used和Total allocations的含義就很明顯了
也就第六和第七項標明的含義

Largest number used表示在同一時刻使用過的最大內存大小
Total allocations表示當前使用的內存大小

⑶ C語言中的內存泄露 怎樣避免與檢測

堆經常會出現兩種類型的問題:1.釋放或改寫仍在使用的內存(稱為:「內存損壞」)。2.未釋放不再使用的內存(稱為:「內存泄露」)。這是最難被調試發現的問題之一
有些程序並不需要管理它們的動態內存的使用。當需要內存時,它們簡單地通過分配來獲得,從來不用擔心如何釋放它。這類程序包括編譯器和其他一些運行一段固定的(或有限的)時間然後終止的程序。當這種類型的程序終止時,所有內存會被自動回收。細心查驗每塊內存是否需要回收純屬浪費時間,因為它們不會再被使用。
其他程序的生存時間要長一點。有些工具如日歷管理器、郵件工具以及操作系統本事經常需要數日及至數周連續運行,並需要管理動態內存的分配和回收。由於C語言通常並不使用垃圾回收器(自動確認並回收不再使用的內存塊),這些C程序在使用malloc()和free()時不得不非常慎重。

堆經常會出現兩種類型的問題:

1.釋放或改寫仍在使用的內存(稱為:「內存損壞」)。
2.未釋放不再使用的內存(稱為:「內存泄露」)。
這是最難被調試發現的問題之一。如果每次已分配的內存塊不再使用而程序並不釋放它們,進程就會一邊分配越來越多的內存,一邊卻並不釋放不再使用的那部分內存。
避免內存泄露
每當調用malloc分配內存時,注意在以後要調用相應的free來釋放它。
如果不知道如何調用free與先前的malloc相對應,那麼很可能已經造成了內存泄露!
一種簡單的方法就是在可能的時候使用alloca()來分配動態內存,以避免上述情況。當離開調用alloca的函數時,它所分配的內存會被自動釋放。
顯然,這並不適用於那些比創建它們的函數生命期更長的結構。但如果對象的生命期在該函數結束前便已經終止,這種建立在堆棧上的動態內存分配是一種開銷很小的選擇。有些人不提倡使用alloca,因為它並不是以後總可移植的方法。如果處理器在硬體上不支持堆棧,alloca()就很難高效地實現。
我們使用「內存泄露」這個詞是因為一種稀有的資源正在被一個進程榨乾。內存泄露的主要可見症狀就是罪魁進程的速度很減慢。原因是體積大的進程更有可能被系統換出,讓別的進程運行,而且大的進程在換進換出時花費的時間也更多。即使泄露的內存本省並不被引用,但它仍用可能存在於頁面中(內容自然是垃圾),這樣就增加了進程的工作頁數量,降低了性能。另外需要注意的一點是,內存泄露往往比忘記釋放的的數據結構要打,因為malloc()所分配的內存通常會圓整為下一個大於申請數量的2的整數次方(如申請212B,會圓整為256B)。在資源有限的情況下,即使引起內存泄露的進程並不運行,整個系統運行速度也會被拖慢。從理論上說,進程的大小有一個上限值,這在不同的操作系統中各不相同。在當前的SunOS版本中,進程的最大地址空間可以多達4GB。事實上,在進程所泄露的內存遠未達到這個數量時,磁碟的交換區早已消耗殆盡。
如何檢測內存泄露
觀察內存泄露是一個兩步驟的過程。首先,使用swap命令觀察還有多少可用的交換空間:
/usr/sbin/swap -s
total:17228K bytes allocated + 5396K reserved=22626K used,29548K available.
在一兩分鍾內鍵入該命令三到四次,看看可用的交換區是否在減少。還可以使用其他一些/usr/bin/*stat工具如netstat、vmstat等。如發現波段有內存被分配且從不釋放,一個可能的解釋就是有個進程出現了內存泄露。

⑷ 如何檢測C語言中的內存漏洞(leak)

在動態分配的內存單元(即由函數malloc()或ealloc()分配的內存單元)不再使用卻沒有被釋放的情況下,會出現內存漏洞。未釋放內存單元本身並不是一種錯誤,編譯程序不會因此報告出錯,程序也不會因此而立即崩潰。但是,如果不再使用而又沒有被釋放的內存單元越來越多,程序所能使用的內存空間就越來越小。最終,當程序試圖要求分配內存時,就會發現已經沒有可用的內存空間。這時,尤其是當程序員沒有考慮到內存分配失敗的可能性時,程序的運行就會出現異常現象。
內存漏洞是最難檢測的錯誤之一,同時也是最危險的錯誤。導致這個問題的編程錯誤很可能出現在程序的開始部分,但只有當程序奠名其妙地使用完內存後,這個問題才會暴露出來。
此時去檢查當前那條導致內存分配失敗的語句是無濟於事的,因為那些分配了內存卻未能按時釋放內存的代碼可能在程序的其它地方。
遺憾的是C語言並沒有為檢測或修復內存漏洞提供現成的方法。除非使用提供這種功能的商業軟體包,否則,程序員就需要以很大的耐心和精力去檢測和修復內存漏洞。最好的辦法是在編寫程序時就充分考慮到內存漏洞的可能性,並小心謹慎地處理這種可能性。
導致內存漏洞的最簡單的也是最常見的原因是忘記釋放分配給臨時緩沖區的內存空間,請看下述程序段:
# include
# include /** Say hello to the user's and put the user's name in UPPERCASE.*/void SayHi( char *name ){char * UpName;int a;UpName = malloc( strlen( name ) +1);
/ * Allocate space for the name * /
for( a =0; a

⑸ [VC]請問如何用C語言來查找內存

你得有個地址范圍吧。。。。然後遍歷,匹配後取地址賦值即可。

⑹ 如何使用Valgrind memcheck工具進行C/C++的內存泄漏檢測

linux下編譯完成後生成可執行文件main,然後運行如下語句:
valgrind --tool=memcheck --show-reachable=yes --log-file=proglog ./main
這個語句的功能是將內存檢測結果存到proglog文件中,文件所在位置與可執行程序main所在位置相同,運行結束後就可以打開proglog文件來看代碼是否存在內存問題了。(文件名proglog和main都可以修改為別的)
常見檢測信息的含義如下:
Invalid read of size XXX:訪問溢出了,對不存在的內存空間進行了讀操作,一般是數組創建的空間不足,或者是索引超過了數組空間大小。通常容易導致段錯誤。
Conditional jump or move depends on uninitialised value(s):字元串、結構體成員等變數沒有初始化,一般不會有影響。
Invalid free():釋放內存變數的方式有問題,例如直接刪除單鏈表變數。會導致段錯誤。
Mismatched free() / delete / delete []:建立變數和釋放變數不統一,malloc建立的變數要用free,new建立的變數要用delete。會導致段錯誤。

⑺ C語言,如何實現搜索內存數據

一般的講,內存里邊雖然說有*G的空間,但有些地方只是掛名存在,實際上是不存在的,所以訪問了就會出錯,所以就要判斷內存是不是為有效地址,
就要用到VirtualQuery獲取指定內存屬性, 根據屬性來判斷能不能進行讀取,
如果能讀取就從調用VirtualQuery中得到的內存信息minfo中獲取當前內存地址的有效區域的大小,然後再進行讀取. 你可以用VC調試來看看,不能訪問的內存就用?號來表示.由於搜所內存是一種運算量龐大的工作,所以,在對比處理要作速度優化處理. 如果數據大於4位元組,請用 long 的數據格式來作對比運算, long 是 char 的處理速度的三倍以上,(個人測試的) 用long處理前端數據,再用 char 作收尾工作. 這是對比處理了.流程就有以下:
判斷地址的有效性->定好搜所范圍->進行對比->輸出結果.

StartAdd 開始地址
EndAdd 結束地址
Data 查找的數據
DataSize 數據大小
void *FindMemory(DWORD StartAdd,DWORD EndAdd,void *Data,DWORD DataSize)
{
MEMORY_BASIC_INFORMATION minfo;
DWORD rt;
while(StartAdd<EndAdd)
{
::VirtualQuery((void*)StartAdd,&minfo,sizeof(MEMORY_BASIC_INFORMATION));
if(minfo.AllocationProtect)
if(minfo.State==MEM_COMMIT||minfo.State==MEM_FREE)
{
char *s=(char*)StartAdd,*e=s+minfo.RegionSize;
for(;s<e&&s+DataSize<=e;s++)
if(memcmp(s,Data,DataSize)==0)
return s;
}
StartAdd=(DWORD)minfo.BaseAddress+minfo.RegionSize;
}
return 0;
}

⑻ c語言怎麼測試內存分配失敗時的代碼

設計一個樁函數:malloc_stub();
在這個函數內直接返回NULL。然後用函數malloc_stub替換malloc,測試如上程序。

⑼ 如何使用工具進行C/C++的內存泄漏檢測

Memcheck是一個內存錯誤檢測器。它有助於使你的程序,尤其是那些用C和C++寫的程序,更加准確。Cachegrind是一個緩存和分支預測分析器。它有助於使你的程序運行更快。Callgrind是一個調用圖緩存生成分析器。它與Cachegrind的功能有重疊,但也收集Cachegrind不收集的一些信息Helgrind是一個線程錯誤檢測器。它有助於使你的多線程程序更加准確。DRD也是一個線程錯誤檢測器。它和Helgrind相似,但使用不同的分析技術,所以可能找到不同的問題。Massif是一個堆分析器。它有助於使你的程序使用更少的內存。DHAT是另一種不同的堆分析器。它有助於理解塊的生命期、塊的使用和布局的低效等問題。SGcheck是一個實驗工具,用來檢測堆和全局數組的溢出。它的功能和Memcheck互補:SGcheck找到Memcheck無法找到的問題,反之亦然。BBV是個實驗性質的SimPoint基本塊矢量生成器。它對於進行計算機架構的研究和開發很有用處。
系統編程中一個重要的方面就是有效地處理與內存相關的問題。你的工作越接近系統,你就需要面對越多的內存問題。有時這些問題非常瑣碎,而更多時候它會演變成一個調試內存問題的惡夢。所以,在實踐中會用到很多工具來調試內存問題。

在本文中,我們將討論最流行的開源內存管理框架 VALGRIND。

摘自 Valgrind.org:

Valgrind是用於構建動態分析工具的探測框架。它包括一個工具集,每個工具執行某種類型的調試、分析或類似的任務,以幫助完善你的程序。Valgrind的架構是模塊化的,所以可以容易地創建新的工具而又不會擾亂現有的結構。

許多有用的工具被作為標准而提供。

Memcheck是一個內存錯誤檢測器。它有助於使你的程序,尤其是那些用C和C++寫的程序,更加准確。
Cachegrind是一個緩存和分支預測分析器。它有助於使你的程序運行更快。
Callgrind是一個調用圖緩存生成分析器。它與Cachegrind的功能有重疊,但也收集Cachegrind不收集的一些信息。
Helgrind是一個線程錯誤檢測器。它有助於使你的多線程程序更加准確。
DRD也是一個線程錯誤檢測器。它和Helgrind相似,但使用不同的分析技術,所以可能找到不同的問題。
Massif是一個堆分析器。它有助於使你的程序使用更少的內存。
DHAT是另一種不同的堆分析器。它有助於理解塊的生命期、塊的使用和布局的低效等問題。
SGcheck是一個實驗工具,用來檢測堆和全局數組的溢出。它的功能和Memcheck互補:SGcheck找到Memcheck無法找到的問題,反之亦然。
BBV是個實驗性質的SimPoint基本塊矢量生成器。它對於進行計算機架構的研究和開發很有用處。
也有一些對大多數用戶沒有用的小工具:Lackey是演示儀器基礎的示例工具;Nulgrind是一個最小化的Valgrind工具,不做分析或者操作,僅用於測試目的。

在這篇文章我們將關注「memcheck」工具。

使用 Valgrind Memcheck

memcheck工具的使用方式如下:

valgrind --tool=memcheck ./a.out
從上面的命令可以清楚的看到, 主要的命令是valgrind,而我們想使用的工具是通過'-tool'選項來指定的. 上面的『a.out』指的是我們想使用memcheck運行的可執行文件.

該工具可以檢測下列與內存相關的問題 :

未釋放內存的使用
對釋放後內存的讀/寫
對已分配內存塊尾部的讀/寫
內存泄露
不匹配的使用malloc/new/new[] 和 free/delete/delete[]
重復釋放內存
注意: 上面列出的並不很全面,但卻包含了能被該工具檢測到的很多普遍的問題.

讓我們一個一個地對上面的場景進行討論:

注意: 下面討論的所有測試代碼都應該使用gcc並且加上-g選項(用來在memcheck的輸出中生成行號)進行編譯. 就想我們之前討論過的 C程序被編譯成可執行文件, 它需要經歷四個不同的階段.

1. 使用未初始化的內存

Code :

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
char *p;

char c = *p;

printf("\n [%c]\n",c);

return 0;
}
在上面的代碼中,我們嘗試使用未初始化的指針 『p』.

讓我們運行Memcheck來看下結果.

$ valgrind --tool=memcheck ./val
==2862== Memcheck, a memory error detector
==2862== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==2862== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for right info
==2862== Command: ./val
==2862==
==2862== Use of uninitialised value of size 8
==2862== at 0x400530: main (valgrind.c:8)
==2862==

[#]
==2862==
==2862== HEAP SUMMARY:
==2862== in use at exit: 0 bytes in 0 blocks
==2862== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==2862==
==2862== All heap blocks were freed -- no leaks are possible
==2862==
==2862== For counts of detected and suppressed errors, rerun with: -v
==2862== Use --track-origins=yes to see where uninitialized values come from
==2862== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)
從上面的輸出可以看到,Valgrind檢測到了未初始化的變數,然後給出了警告(上面加粗的幾行(譯者註:貌似上面沒有加粗的)).

2. 在內存被釋放後進行讀/寫

Code :

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
char *p = malloc(1);
*p = 'a';

char c = *p;

printf("\n [%c]\n",c);

free(p);
c = *p;
return 0;
}
上面的代碼中,我們有一個釋放了內存的指針 『p』 然後我們又嘗試利用指針獲取值.

讓我們運行memcheck來看一下Valgrind對這種情況是如何反應的.

$ valgrind --tool=memcheck ./val
==2849== Memcheck, a memory error detector
==2849== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==2849== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for right info
==2849== Command: ./val
==2849==

[a]
==2849== Invalid read of size 1
==2849== at 0x400603: main (valgrind.c:30)
==2849== Address 0x51b0040 is 0 bytes inside a block of size 1 free'd
==2849== at 0x4C270BD: free (vg_replace_malloc.c:366)
==2849== by 0x4005FE: main (valgrind.c:29)
==2849==
==2849==
==2849== HEAP SUMMARY:
==2849== in use at exit: 0 bytes in 0 blocks
==2849== total heap usage: 1 allocs, 1 frees, 1 bytes allocated
==2849==
==2849== All heap blocks were freed -- no leaks are possible
==2849==
==2849== For counts of detected and suppressed errors, rerun with: -v
==2849== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)
從上面的輸出內容可以看到,Valgrind檢測到了無效的讀取操作然後輸出了警告 『Invalid read of size 1′.

另注,使用gdb來調試c程序.

3. 從已分配內存塊的尾部進行讀/寫

Code :

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
char *p = malloc(1);
*p = 'a';

char c = *(p+1);

printf("\n [%c]\n",c);

free(p);
return 0;
}
在上面的代碼中,我們已經為『p』分配了一個位元組的內存,但我們在將值讀取到 『c』中的時候使用的是地址p+1.

現在我們使用Valgrind運行上面的代碼 :

$ valgrind --tool=memcheck ./val
==2835== Memcheck, a memory error detector
==2835== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==2835== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for right info
==2835== Command: ./val
==2835==
==2835== Invalid read of size 1
==2835== at 0x4005D9: main (valgrind.c:25)
==2835== Address 0x51b0041 is 0 bytes after a block of size 1 alloc'd
==2835== at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==2835== by 0x4005C5: main (valgrind.c:22)
==2835==

[]
==2835==
==2835== HEAP SUMMARY:
==2835== in use at exit: 0 bytes in 0 blocks
==2835== total heap usage: 1 allocs, 1 frees, 1 bytes allocated
==2835==
==2835== All heap blocks were freed -- no leaks are possible
==2835==
==2835== For counts of detected and suppressed errors, rerun with: -v
==2835== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)
同樣,該工具在這種情況下也檢測到了無效的讀取操作.

4. 內存泄露

Code:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
char *p = malloc(1);
*p = 'a';

char c = *p;

printf("\n [%c]\n",c);

return 0;
}
在這次的代碼中, 我們申請了一個位元組但是沒有將它釋放.現在讓我們運行Valgrind看看會發生什麼:

$ valgrind --tool=memcheck --leak-check=full ./val
==2888== Memcheck, a memory error detector
==2888== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==2888== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for right info
==2888== Command: ./val
==2888==

[a]
==2888==
==2888== HEAP SUMMARY:
==2888== in use at exit: 1 bytes in 1 blocks
==2888== total heap usage: 1 allocs, 0 frees, 1 bytes allocated
==2888==
==2888== 1 bytes in 1 blocks are definitely lost in loss record 1 of 1
==2888== at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==2888== by 0x400575: main (valgrind.c:6)
==2888==
==2888== LEAK SUMMARY:
==2888== definitely lost: 1 bytes in 1 blocks
==2888== indirectly lost: 0 bytes in 0 blocks
==2888== possibly lost: 0 bytes in 0 blocks
==2888== still reachable: 0 bytes in 0 blocks
==2888== suppressed: 0 bytes in 0 blocks
==2888==
==2888== For counts of detected and suppressed errors, rerun with: -v
==2888== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)
輸出行(上面加粗的部分)顯示,該工具能夠檢測到內存的泄露.

注意: 在這里我們增加了一個選項『–leak-check=full』來得到內存泄露的詳細細節.

5. 不匹配地使用malloc/new/new[] 和 free/delete/delete[]

Code:

#include <stdio.h>
#include <stdlib.h>
#include<iostream>

int main(void)
{
char *p = (char*)malloc(1);
*p = 'a';

char c = *p;

printf("\n [%c]\n",c);
delete p;
return 0;
}
上面的代碼中,我們使用了malloc()來分配內存,但是使用了delete操作符來刪除內存.

注意 : 使用g++來編譯上面的代碼,因為delete操作符是在C++中引進的,而要編譯C++需要使用g++.

讓我們運行來看一下 :

$ valgrind --tool=memcheck --leak-check=full ./val
==2972== Memcheck, a memory error detector
==2972== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==2972== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for right info
==2972== Command: ./val
==2972==

[a]
==2972== Mismatched free() / delete / delete []
==2972== at 0x4C26DCF: operator delete(void*) (vg_replace_malloc.c:387)
==2972== by 0x40080B: main (valgrind.c:13)
==2972== Address 0x595e040 is 0 bytes inside a block of size 1 alloc'd
==2972== at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==2972== by 0x4007D5: main (valgrind.c:7)
==2972==
==2972==
==2972== HEAP SUMMARY:
==2972== in use at exit: 0 bytes in 0 blocks
==2972== total heap usage: 1 allocs, 1 frees, 1 bytes allocated
==2972==
==2972== All heap blocks were freed -- no leaks are possible
==2972==
==2972== For counts of detected and suppressed errors, rerun with: -v
==2972== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)
從上面的輸出可以看到 (加粗的行), Valgrind清楚的說明了『不匹配的使用了free() / delete / delete []『

你可以嘗試在測試代碼中使用'new'和'free'進行組合來看看Valgrind給出的結果是什麼.

6. 兩次釋放內存

Code :

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
char *p = (char*)malloc(1);
*p = 'a';

char c = *p;
printf("\n [%c]\n",c);
free(p);
free(p);
return 0;
}
在上面的代碼中, 我們兩次釋放了'p'指向的內存. 現在讓我們運行memcheck :

$ valgrind --tool=memcheck --leak-check=full ./val
==3167== Memcheck, a memory error detector
==3167== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==3167== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for right info
==3167== Command: ./val
==3167==

[a]
==3167== Invalid free() / delete / delete[]
==3167== at 0x4C270BD: free (vg_replace_malloc.c:366)
==3167== by 0x40060A: main (valgrind.c:12)
==3167== Address 0x51b0040 is 0 bytes inside a block of size 1 free'd
==3167== at 0x4C270BD: free (vg_replace_malloc.c:366)
==3167== by 0x4005FE: main (valgrind.c:11)
==3167==
==3167==
==3167== HEAP SUMMARY:
==3167== in use at exit: 0 bytes in 0 blocks
==3167== total heap usage: 1 allocs, 2 frees, 1 bytes allocated
==3167==
==3167== All heap blocks were freed -- no leaks are possible
==3167==
==3167== For counts of detected and suppressed errors, rerun with: -v
==3167== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)
從上面的輸出可以看到(加粗的行), 該功能檢測到我們對同一個指針調用了兩次釋放內存操作.

熱點內容
微信視頻如何重新緩存 發布:2025-01-21 04:44:41 瀏覽:879
pdf壓縮文件大小 發布:2025-01-21 04:40:24 瀏覽:798
linux解壓文件到指定 發布:2025-01-21 04:38:36 瀏覽:874
自己做的安卓app怎麼下載 發布:2025-01-21 04:35:07 瀏覽:163
機頂盒加密頻道 發布:2025-01-21 04:26:48 瀏覽:318
騰訊應用加密 發布:2025-01-21 04:24:38 瀏覽:988
無法訪問f 發布:2025-01-21 04:24:36 瀏覽:539
sql實時 發布:2025-01-21 04:24:27 瀏覽:998
怎麼在linux伺服器上配ip地址 發布:2025-01-21 04:22:10 瀏覽:251
咖搭姆編程 發布:2025-01-21 04:19:45 瀏覽:674