Code to check for memory leaks I want to write a header file for c++. When included in a program, the header file overloads the new and delete operators so that it can count the number of allocations and deallocations. The header file will also print out the number of allocations and deallocations when the program exits. Is this the proper way to go about doing that? Will this code cause any problems or leave any gaps? The header file is only meant to be included when debugging.

#pragma once
#include &lt;cstdint&gt;
#include &lt;cstdlib&gt;

size_t __allocations = 0;
void* operator new(std::size_t sz) {
    ++__allocations;
    return std::malloc(sz);
}

size_t __array_allocations = 0;
void* operator new[](std::size_t sz) {
    ++__array_allocations;
    return std::malloc(sz);
}
size_t __deallocations = 0;
void operator delete(void* ptr) noexcept
{
    ++__deallocations;
    std::free(ptr);
}
size_t __array_deallocations = 0;
void operator delete[](void* ptr) noexcept
{
    ++__array_deallocations;
    std::free(ptr);
}

#include &lt;iostream&gt;
struct EnsureOutput
{
    ~EnsureOutput()
    {
        using namespace std;
        cout &lt;&lt; "Allocations:   " &lt;&lt; __allocations &lt;&lt; endl;
        cout &lt;&lt; "Deallocations: " &lt;&lt; __deallocations &lt;&lt; endl;
        cout &lt;&lt; "Array Allocations:   " &lt;&lt; __array_allocations &lt;&lt; endl;
        cout &lt;&lt; "Array Deallocations: " &lt;&lt; __array_deallocations &lt;&lt; endl;
        if(__allocations == __deallocations &amp;&amp; __array_deallocations == __array_deallocations)
        {
            cout &lt;&lt; "No leaks discovered" &lt;&lt; endl;
        }
        else
        {
            cout &lt;&lt; "You have a memory leak." &lt;&lt; endl;
        }
    }
};
EnsureOutput o = {};
Identifiers containing two consecutive underscores are reserved for use by the C++ implementation for any purpose.  That means they can even be macros!  Don't use __ in your identifiers; if you want to keep them separate from user code, you can use a suitable namespace (ideally an anonymous namespace).

Another observation is that this code only keeps count of operations - a double delete could easily cancel a leak and lead your code to report "No leaks discovered".

Although you've kept using namespace std; within a sensible, small scope, I think I'd still prefer using std::cout; using std::endl or just fully-qualified names there.  Consider using std::cerr instead for this kind of information that's not part of normal program output - that may be essential when used in a pipeline.