#ifndef MALLOC_CHK_H
#define MALLOC_CHK_H

// operator new を乗っ取るため <new>をinclude済みに
#define _NEW_
#define _NEW
#define __NEW_H 1

#undef       malloc
#undef       free
#undef new
#undef delete

// 手抜きで実体.
unsigned g_my_malloc_count = 0;
unsigned g_my_free_count   = 0;

void         my_malloc_count_init() { g_my_malloc_count = g_my_free_count = 0; }
inline void* my_malloc(size_t size) {   ++g_my_malloc_count; return ::malloc(size); }
inline void  my_free(void* p)       { ++g_my_free_count; ::free(p); }

#define my_malloc_count_disp()      fprintf(stderr, "\tmalloc count=%5d  free count=%5d\n", g_my_malloc_count, g_my_free_count)
#define malloc(sz)                  my_malloc(sz)
#define free(p)                     my_free(p)

namespace std {
    struct nothrow_t { };
    extern const nothrow_t nothrow;
}

inline void* operator new(std::size_t, void* p) throw() { return p; }
inline void* operator new[](std::size_t, void* p) throw() { return p; }
inline void* operator new(std::size_t size) throw() { return my_malloc(size); }
inline void* operator new[](std::size_t size) throw() { return my_malloc(size); }
inline void* operator new(std::size_t size, const std::nothrow_t&) throw() { return my_malloc(size); }
inline void* operator new[](std::size_t size, const std::nothrow_t&) throw() { return my_malloc(size); }
inline void  operator delete(void* p) throw() { return my_free(p); }
inline void  operator delete[](void* p) throw() { return my_free(p); }

#include <memory>

#endif