我知道如何使用malloc()
和free()
來分配內存,但是還有一個標準的C函數來檢查剩餘的內存量,所以我可以定期調用它來確保我的代碼沒有內存泄漏?C - 檢查可用的公羊?
我唯一能想到的就是在無限循環中調用malloc(1)
,直到它返回一個錯誤,但是不應該有更有效的方法嗎?
我知道如何使用malloc()
和free()
來分配內存,但是還有一個標準的C函數來檢查剩餘的內存量,所以我可以定期調用它來確保我的代碼沒有內存泄漏?C - 檢查可用的公羊?
我唯一能想到的就是在無限循環中調用malloc(1)
,直到它返回一個錯誤,但是不應該有更有效的方法嗎?
不,沒有標準的C函數來做到這一點。有一些特定於平臺的功能可用於執行某些類型的查詢(如工作集大小),但這些功能可能不會有幫助,因爲有時已正確使用內存free()
d仍被認爲由操作系統分配因爲malloc
實現可能會將釋放的內存保留在池中。
如果您想檢查內存泄漏情況,我強烈建議您使用像Valgrind這樣的工具,它可以在各種虛擬機中運行程序,並可以跟蹤內存泄漏以及其他功能。
如果您在Windows上運行,則可以使用_CrtDbgReport
和/或_CrtSetDbgFlag
來檢查內存泄漏。
該程序是在Cortex M0 CPU上運行的固件,以及使用了大量ARM特定的調用/指令,所以我認爲很難分析Valgrind,並且我沒有足夠的內存來運行我自己的代碼,更不用說添加虛擬機了。 – Muis
在這種情況下,測量在執行開始時你擁有多少內存,並在'malloc'和'free'周圍編寫包裝函數,從你的起始點開始遞減和遞增,就像loreb在另一個答案中所表明的那樣。 –
如果你可以買得起#ifdef'ing一個調試版本(可能在模擬器!),你可以建立一個malloc/free的調試版本,跟蹤當前使用的字節數,並「打印」它會定期(再次 - 只在調試版本中,可能在仿真器下)在任何用於調試的輸出設備上(一個LED?),並查看它是否繼續增加。
標準的關鍵是要與新分配的內存分配在一起的sizeof(爲size_t)以上的要求,因而存儲大小 - 但如果你正在寫固件我想你已經知道了:)
所以...你有模擬器嗎?
編輯:我很習慣以GHz運行的計算機,它一開始並沒有出現在我身上,但當然你可以做的另一件事是隻計算分配的數量,而不是它們的大小 - 我無法想象這可能會佔用太多內存來運行。
如果在您的系統中malloc()
始終分配物理內存,您可以重複調用malloc()
,其大小不是1,而是通過連續冪爲2。這會更有效率。下面是如何做到這一點的一個例子。
另一方面,如果malloc()
只分配虛擬地址空間而沒有將物理內存映射到虛擬地址空間,則這不會給你想要的。
示例代碼:
#include <stdio.h>
#include <stdlib.h>
void* AllocateLargestFreeBlock(size_t* Size)
{
size_t s0, s1;
void* p;
s0 = ~(size_t)0^(~(size_t)0 >> 1);
while (s0 && (p = malloc(s0)) == NULL)
s0 >>= 1;
if (p)
free(p);
s1 = s0 >> 1;
while (s1)
{
if ((p = malloc(s0 + s1)) != NULL)
{
s0 += s1;
free(p);
}
s1 >>= 1;
}
while (s0 && (p = malloc(s0)) == NULL)
s0 ^= s0 & -s0;
*Size = s0;
return p;
}
size_t GetFreeSize(void)
{
size_t total = 0;
void* pFirst = NULL;
void* pLast = NULL;
for (;;)
{
size_t largest;
void* p = AllocateLargestFreeBlock(&largest);
if (largest < sizeof(void*))
{
if (p != NULL)
free(p);
break;
}
*(void**)p = NULL;
total += largest;
if (pFirst == NULL)
pFirst = p;
if (pLast != NULL)
*(void**)pLast = p;
pLast = p;
}
while (pFirst != NULL)
{
void* p = *(void**)pFirst;
free(pFirst);
pFirst = p;
}
return total;
}
int main(void)
{
printf("Total free: %zu\n", GetFreeSize());
printf("Total free: %zu\n", GetFreeSize());
printf("Total free: %zu\n", GetFreeSize());
printf("Total free: %zu\n", GetFreeSize());
printf("Total free: %zu\n", GetFreeSize());
return 0;
}
輸出(ideone):
Total free: 266677120
Total free: 266673024
Total free: 266673024
Total free: 266673024
Total free: 266673024
爲什麼不直接使用的valgrind在你的程序檢查是否漏水? – Mike
請注意,在無限循環中調用malloc可能永遠不會失敗,因爲大多數系統僅在_first touch_上分配內存。 – Ben
相關:http://stackoverflow.com/questions/2513505/how-to-get-available-memory-cg –