override standart allocator

I want to see how memory consumed by std::set, in particular how bytes are ordered for tree itself and data in that tree. So i just overrided allocator in next way:
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
// set::insert
#include <iostream>
#include <set>
#include <memory>
using namespace std;

template <typename T>
class my_allocator : public allocator<T>
{
public:
  T* allocate (size_t n, const void* hint=0)
  {
    cout<<"Request to allocate "<<n <<endl;
    allocator<T>::allocate(n, hint);
  }
};

#define my_set_t set<int, less<int>, my_allocator<int> >

int main ()
{
  my_set_t myset;
  my_set_t::iterator it;
  pair<my_set_t::iterator,bool> ret;
  // set some initial values:
  for (int i=1; i<=5; i++) 
    myset.insert(i*10);    // set: 10 20 30 40 50
  ret = myset.insert(20);               // no new element inserted
  if (ret.second==false) 
    it=ret.first;  // "it" now points to element 20
  myset.insert (it,25);                 // max efficiency inserting
  myset.insert (it,24);                 // max efficiency inserting
  myset.insert (it,26);                 // no max efficiency inserting
  //
  int myints[]= {5,10,15};              // 10 already in set, not inserted
  myset.insert (myints,myints+3);
  cout << "myset contains:";
  for (it=myset.begin(); it!=myset.end(); it++)
    cout << " " << *it;
  cout << endl;
  return 0;
}


I should explicitly write
 
T* allocate (size_t n, const void* hint=0)

instead of

 
pointer allocate (size_type n, allocator<void>::const_pointer hint=0)


because of special rules in templates inheritance mechanizm. But it seems that
allocate wasn't overrided in that way. How to overcome such behaviour?
http://en.wikipedia.org/wiki/Allocator_%28C%2B%2B%29

Scrolll down to the requirements section.
OK. But inheritance supposed to fulfii all conditions, isn't it? In fact, it is. At least code compiled and run. Or should i do smth like types redefinition?
#define, really?

Anyway, std::set does not allocate objects of type int. It allocates nodes of some tree, which have some other type (_Rb_tree_node<int> in GCC, for example).

In order to allocate those nodes, it has to obtain a suitable allocator. To obtain that from the allocator you provided, it uses the rebind template.

Since you derived your allocator from std::allocator, it sees the base class's rebind, which returns std::allocator<NodeType>, and that's what it uses to allocate those nodes.

(those wikipedia requirements are pretty old now, c++11 made it so much easier to write allocators)
Last edited on
Now i see! Thanks!


P.S.

#define, really?

Why not in tests? :)
Topic archived. No new replies allowed.