LoginSignup
9
9

More than 5 years have passed since last update.

(malloc/freeを用いた) デバッグ用 allocator

Last updated at Posted at 2013-12-19
#include <cstdio>
#include <cstdlib>
#include <new>
#include <typeinfo>

namespace epi {

  template<typename T> struct mallocator {
    typedef T value_type;
    template<typename U> mallocator(const mallocator<U>&) {}

    mallocator() {}
    bool operator==(const mallocator&) const{ return true;  }
    bool operator!=(const mallocator&) const{ return false; }

    T* allocate(const size_t n) const {
      if ( n == 0 ) 
        return nullptr;
      if (n > static_cast<size_t>(-1) / sizeof(T) )
        throw std::bad_array_new_length();
      void* pv = std::malloc(n * sizeof(T));
      if ( !pv )
        throw std::bad_alloc();
      printf("%d %s MALLOC : %p\n", n, typeid(T).name(), pv);
      return static_cast<T*>(pv);
    }

    void deallocate(T* const p, size_t n) const {
        printf("%d %s FREE :   %p\n", n, typeid(T).name(), p);
        std::free(p);
    }

    void construct(T* p, const T& val) { new ((void*)p) T(val); }

    void destroy(T* p) { p->T::~T(); }

    template<typename Other> struct rebind {
        typedef mallocator<Other> other;
    };
  };

}

/*
 * おためし
 */
#include <vector>
#include <string>
#include <iostream>

// epi::mallocator を使った vector と string (alias templates)
template<typename T> using my_vec = std::vector<T, epi::mallocator<T>>;
template<typename T> using my_str = std::basic_string<T, std::char_traits<T>, epi::mallocator<T>>;

using namespace std;

int main() {
  my_vec<int> vi;
  my_vec<my_str<char>> vs;
  vi.emplace_back(1); vi.emplace_back(2); vi.emplace_back(3);
  vs.emplace_back("one"); vs.emplace_back("two"); vs.emplace_back("three");
  for (int n : vi) { cout << n << ' '; } cout << endl;
  for (my_str<char> s : vs) { cout << s << ' '; } cout << endl;
}

/* 実行結果: (Visaul C++ 2013)
1 int MALLOC : 00B3B1D0
2 int MALLOC : 00B3B0E0
1 int FREE : 00B3B1D0
3 int MALLOC : 00B37B18
2 int FREE : 00B3B0E0
1 class std::basic_string<char, struct std::char_traits<char>, struct epi::mallocator<char> > MALLOC : 00B34F58
2 class std::basic_string<char, struct std::char_traits<char>, struct epi::mallocator<char> > MALLOC : 00B37810
1 class std::basic_string<char, struct std::char_traits<char>, struct epi::mallocator<char> > FREE : 00B34F58
3 class std::basic_string<char, struct std::char_traits<char>, struct epi::mallocator<char> > MALLOC : 00B3AF18
2 class std::basic_string<char, struct std::char_traits<char>, struct epi::mallocator<char> > FREE : 00B37810
1 2 3
one two three
3 class std::basic_string<char, struct std::char_traits<char>, struct epi::mallocator<char> > FREE : 00B3AF18
3 int FREE : 00B37B18
*/
9
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
9