6
\$\begingroup\$

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 <cstdint>
#include <cstdlib>

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 <iostream>
struct EnsureOutput
{
    ~EnsureOutput()
    {
        using namespace std;
        cout << "Allocations:   " << __allocations << endl;
        cout << "Deallocations: " << __deallocations << endl;
        cout << "Array Allocations:   " << __array_allocations << endl;
        cout << "Array Deallocations: " << __array_deallocations << endl;
        if(__allocations == __deallocations && __array_deallocations == __array_deallocations)
        {
            cout << "No leaks discovered" << endl;
        }
        else
        {
            cout << "You have a memory leak." << endl;
        }
    }
};
EnsureOutput o = {};
\$\endgroup\$
  • 4
    \$\begingroup\$ Any reason not to use something like Google Perftools? \$\endgroup\$ – yuri Jun 2 '17 at 20:54
  • 3
    \$\begingroup\$ Also valgrind and MSVS tools are available depending on platform. \$\endgroup\$ – Incomputable Jun 2 '17 at 22:49
  • \$\begingroup\$ Well, it seems like you still use new and delete in productive C++-Code. In case you do, learn about better methods for dynamically allocating objects. \$\endgroup\$ – The Techel Jun 4 '17 at 18:13
2
\$\begingroup\$

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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.