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 = {};
-
4\$\begingroup\$ Any reason not to use something like Google Perftools? \$\endgroup\$yuri– yuri2017年06月02日 20:54:42 +00:00Commented Jun 2, 2017 at 20:54
-
3\$\begingroup\$ Also valgrind and MSVS tools are available depending on platform. \$\endgroup\$Incomputable– Incomputable2017年06月02日 22:49:57 +00:00Commented Jun 2, 2017 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– The Techel2017年06月04日 18:13:32 +00:00Commented Jun 4, 2017 at 18:13
1 Answer 1
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.