1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
|
#include <iostream>
#include <cstdlib>
#include <map>
#include <cassert>
namespace debug
{
extern std::map< void*, std::tuple<const char*, int, std::size_t> > allocs ;
void* traced_malloc( std::size_t sz, const char* file, int line )
{
void* const p = (malloc)(sz) ;
allocs[p] = { file, line, sz } ;
std::clog << file << " : " << line << " malloc " << sz << " bytes at " << p << '\n' ;
return p ;
}
void traced_free( void* p, const char* file, int line )
{
std::clog << file << " : " << line << " free memory at " << p << '\n' ;
assert( allocs.erase(p) == 1 ) ;
free(p) ;
}
void dump_allocs()
{
for( const auto& pair : allocs )
{
auto [file,line,sz] = pair.second ;
std::cout << "block at " << pair.first << " size: " << sz
<< " bytes allocated from: " << file << " : " << line << '\n' ;
}
}
}
#define malloc(sz) debug::traced_malloc( sz, __FILE__, __LINE__ )
#define free(p) debug::traced_free( p, __FILE__, __LINE__ )
int main()
{
auto p = malloc(100) ; // debug::traced_malloc
free(p) ; // debug::traced_free
malloc(200) ; // debug::traced_malloc
p = (malloc)(300) ; // ::malloc
(free)(p) ; // ::free
(malloc)(400) ; // ::malloc
std::cout << "\nun-freed blocks:\n" ;
debug::dump_allocs() ;
}
std::map< void*, std::tuple<const char*, int, std::size_t> > debug::allocs ;
|