I am primarily a Linux developer however, I have inherited a windows dll with a memory leak. I know the cause and believe I have fixed it. I would like to check this in the unit tests. The unit tests use the builtin cppunit test framework, which is no relation to the cppunit framework I normally use on Linux. i.e.
#include "CppUnitTest.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
What I would like to do is measure the memory usage before and after a block of code and check that it has not changed - which would indicate a memory leak. Or similarly, to check that an allocator type function allocates exactly the amount of memory that a subsequent destructor type function frees.
Is there suitable API I can use to reliably get the current memory usage?
I naively tried the following:
size_t getMemoryUsage()
{
PROCESS_MEMORY_COUNTERS pmc;
auto processHandle = GetCurrentProcess();
if (GetProcessMemoryInfo(processHandle, &pmc, sizeof(pmc)))
{
return pmc.WorkingSetSize;
}
else
{
Assert::Fail(L"Unable to get memory usage for current process");
}
return 0;
}
This gives me the memory usage of the current process. Unfortunately this does not accurately reflect the allocations and frees going on. I think that if I free memory the OS may still hold it in reserve for the application to use later. The working set is the OS's allocation to the process not the memory it actually uses internally.
I tried changing this to PrivateUsage via What is private bytes, virtual bytes, working set? but this does not always seem to change after a malloc.
Is there a suitable API which will do this for me? Perhaps a library that can substitute an instrumented malloc like you might do with LD_PRELOAD on Linux? See ld-preload-equivalent-for-windows-to-preload-shared-libraries
There are several similar questions here - for example memory leak unit test c++.
This question is specific to the case of unit testing a DLL using cppunit in visual studio.
The DLL does not expose an interface for a allocator that could be overridden. I think my best option at present may be to add one. I would rather avoid making extensive changes if there is a simpler way. An answer confirming that this is the only way will be accepted.