Reputation: 307
My goal is to write platform-independent free memory checker. Something like:
std::size_t before = MemoryAllocated();
do_stuff(); //some algorithm that uses malloc, free, new, delete, etc
std::size_t after = MemoryAllocated();
if( after != before )
printf( "ALARM! MEMORY LEAKS!\n" );
On POSIX there is mallinfo(), which provides pretty comprehensive free memory stats, one of the fields is uordblks, which seems to show exactly what I want. It includes the overhead - for instance it shows that new int on my machine allocates 32 bytes. But in the end of the day if you deallocaed everything - it shows 0, if you forgot something - it is non-zero.
On Windows there is _heapwalk(). It is a bit more complicated than mallinfo() - you need to iterate through heap chunks and compute the size yourself. And even after you did it, the result isn't quite what I expect:
int main()
{
std::cout << "start " << MemoryAllocated() << std::endl;
char *charr = new char[100];
std::cout << "after new char[100] " << MemoryAllocated() << std::endl;
int *pint = new int;
std::cout << "after new int " << MemoryAllocated() << std::endl;
delete[] charr;
std::cout << "after delete[] chars " << MemoryAllocated() << std::endl;
delete pint;
std::cout << "after delete int " << MemoryAllocated() << std::endl;
return 0;
}
results in:
start 26980
after new char[100] 31176
after new int 31180
after delete[] chars 31080
after delete int 31076
Looks like it allocates some initial 4 kbytes of memory for his internal needs on my first request to allocated memory, but then it shows current status accurately.
I tried to preallocate something before starting the real count - it doesn't help.
Can anybody hint me, how to do it properly on Windows?
Upvotes: 2
Views: 588
Reputation: 500
I wrote a C code that seems to work but in a weird way, seems, like your results, that there is ~4K memory that allocated in the beginning, but it allocated between first check to the second. So if we ignore it we get correct answer:
#include <stdio.h>
#include <stdlib.h>
int MemoryAllocated()
{
_HEAPINFO hinfo;
int heapstatus;
hinfo._pentry = NULL;
int ans = 0;
while((heapstatus = _heapwalk(&hinfo)) == _HEAPOK)
{
if(hinfo._useflag == _USEDENTRY)
{
ans += hinfo._size;
}
}
switch(heapstatus)
{
case _HEAPEMPTY:
printf("ERROR - empty heap\n");
exit(-1);
break;
case _HEAPBADPTR:
printf("ERROR - bad pointer to heap\n");
exit(-1);
break;
case _HEAPBADBEGIN:
printf("ERROR - bad start of heap\n");
exit(-1);
break;
case _HEAPBADNODE:
printf("ERROR - bad node in heap\n");
exit(-1);
break;
}
return ans;
}
int main(void) {
int dummy_start_alloc, start_alloc, end_alloc;
dummy_start_alloc = MemoryAllocated();
printf("dummy start %d\n", dummy_start_alloc);
start_alloc = MemoryAllocated();
printf("real start %d\n", start_alloc);
if(dummy_start_alloc != start_alloc)
{
printf("It is weird why dummy start is different than second start\n");
}
char *charr = malloc(sizeof(char[100]));
printf("after malloc char[100] %d\n", MemoryAllocated());
int *pint = malloc(sizeof(int));
printf("after malloc int %d\n", MemoryAllocated());
free(charr);
printf("after free chars %d\n", MemoryAllocated());
free(pint);
end_alloc = MemoryAllocated();
printf("after free int %d\n", end_alloc);
if(start_alloc == end_alloc)
{
printf("no memory leak detected");
}
else
{
printf("ERROR - memory leak detected");
}
return EXIT_SUCCESS;
}
Output for me is:
dummy start 14878
real start 18974
It is weird why dummy start is different than second start
after malloc char[100] 19074
after malloc int 19078
after free chars 18978
after free int 18974
no memory leak detected
Upvotes: 0