2

I am trying to create a tracking class to track the memory allocation. e.g print how many bytes are allocated in the application. For the variables that using new/delete operator. I could use operator new/delete. But how about the memory allocated by smart pointers?

#include <memory>
#include <iostream>

using namespace std;
template<T>
class MemoryTracking : std::enable_shared_from_this<MemoryTracking<T> >
{
public:
  static size_t s_total;
  void* operator new (const size_t s)
  { 
    s_total += s; 
    return ::operator new[](s);
  }
  void* operator new[](const size_t s)
  { 
    s_total +=s; 
    return ::operator new[](s);
  }
  void delete(void *p, size_t s) noexcept
  {
    s_total -= s;
    ::operator delete(p);
  }
  void delete[](void *p, size_t s) noexcept
  {
    s_total -= s;
    ::operator delete[](p);
  }

  // for shared_ptr
  MemoryTracking() throw() {};
  MemoryTracking(const MemoryTracking& other) throw() {};

  MemoryTracking<T>& operator = (const MemoryTracking<T>& other) { return *this; }
  MemoryTracking<T>& operator = (const MemoryTracking& other) { return *this; }
  ~MemoryTracking() {}

  T* allocate(size_t n, const void* hint = 0)
  {
    return static_cast<T*>(::operator new(n * sizeof(T)));
  }

  void deallocate(T* ptr, size_t n)
  {
    ::operator delete(ptr);
  }

  template <typename U>
  inline bool operator == (const MemoryTracking<U>&)
  {
    return true;
  }

  template <typename U>
  inline bool operator != (const MemoryTracking<U>& obj)
  {
    return !(*shared_from_this() == obj);
  }
};

class A : public MemoryTracking<A>
{
}

int main()
{
  auto ptr = make_shared<A>();
  cout << MemoryTracking::s_total << endl;
}
r0n9
  • 2,505
  • 1
  • 29
  • 43
  • 1
    [This](http://stackoverflow.com/questions/9675225/boostmake-shared-is-not-calling-placement-operator-new) seems to answer your question. `make_shared` is (probably) using global placement new. – Sam Apr 30 '16 at 06:51
  • kind of, but not really, I know that ideally, I need to create shared_ptr by using allocate_shared which takes an allocator_traits to allocate memory. But I just not sure how exactly I can do it. And I am not sure how to track memory allocated by unique_ptr since there is no allocate_unique. – r0n9 Apr 30 '16 at 10:38

1 Answers1

2

If you want to track all memory allocated in your application, you may want to instead override malloc(), realloc(), calloc(), and free(). By overriding those four, you will capture not only C++ allocations but also C ones.

For how to wrap functions like malloc(), see: How to reimplement (or wrap) a syscall function in linux? or Globally override malloc in visual c++

Community
  • 1
  • 1
John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • Thanks for your answer, I am on windows. It seems I cannot overload malloc, realloc, calloc and free on win system. – r0n9 Apr 30 '16 at 20:02
  • You can do it on Windows too--see here: http://stackoverflow.com/questions/1316018/globally-override-malloc-in-visual-c – John Zwinck May 01 '16 at 02:06