By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,652 Members | 1,694 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,652 IT Pros & Developers. It's quick & easy.

std::allocator

P: n/a
Hi,

can anybody tell me where I can get the boiler plate code for
std::allocator. I need to have my version of new and delete called and
want to get reference code. My compilers headers are all over the place
with #ifdefs and what not, I'd like a clean copy.
thanks much

GrahamO

Nov 22 '05 #1
Share this Question
Share on Google+
7 Replies


P: n/a
Gr*****@nospam.com wrote:
Hi,

can anybody tell me where I can get the boiler plate code for
std::allocator.
Implementation defined.
I need to have my version of new and delete called and
want to get reference code. My compilers headers are all over the place
with #ifdefs and what not, I'd like a clean copy.


Just define new and delete operators for your class, they will get
called instead of the global ones.

# include <iostream>

class Test
{
public:
void *operator new(std::size_t s)
{
std::cout << "hello";
return 0;
}

void operator delete(void *p)
{
std::cout << "goodbye";
}
};

int main()
{
delete new Test; // hellogoodbye
}
Jonathan

Nov 22 '05 #2

P: n/a
Is it safe to do that ? I mean, I'm using custom iterators for legacy
containers already and I need my version of new and delete to be called
by STL algorithms (which already use my custom Iterators).

i.e. I am going to be using stl algorithms with custom containers and
it's essential that our version of new and delete be called. Fair
enough, if yes, just wanted to check.

thanks

G

Nov 22 '05 #3

P: n/a
Gr*****@nospam.com wrote:
Is it safe to do that ? I mean, I'm using custom iterators for legacy
containers already and I need my version of new and delete to be called
by STL algorithms (which already use my custom Iterators).

i.e. I am going to be using stl algorithms with custom containers and
it's essential that our version of new and delete be called. Fair
enough, if yes, just wanted to check.

thanks

G


Actually, my recollection/experience is that STL containers will use
placement new rather than "regular" operator new. (Since the allocation
of memory is handled separately by the Allocator.) Thus you need to define:

void* operator new(size_t size, void* loc);

In fact, if you only define:

void* operator new (size_t size);

you will likely get compilation errors because that definition will hide
the global placement new needed by the STL containers.

Mark

// EXAMPLE

#include <new>
#include <list>

struct C
{
// If you define this...
void* operator new(std::size_t size) {return ::operator new(size);}
// then you need to define this...
void* operator new(std::size_t size, void* loc) {
return ::operator new(size,loc);}
};

int main()
{
std::list<C> cList;
// otherwise this won't compile:
cList.push_back(C());
}
Nov 22 '05 #4

P: n/a
The standard containers won't ever call new to allocate memory -
they'll use
allocator supplied with template instantiation and placement new to
invoke
the constructor.

What you probably want to do is to create custom allocator, but not for
use
by new. (I guess your original question was just that).

The API requirements for the allocator are as follows:
(but please, don't quote me on this and better find a refernce
to it in the standard).

template <typename T>
class allocator
{
public:
//Typedefs
typedef T value_type;
typedef value_type * pointer;
typedef value_type const* const_pointer;
typedef value_type& reference;
typedef value_type const& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
public:
//The rebind
template <typename U>
struct rebind
{
typedef allocator<U> other;
};
public:
//Constructors/Destructors
allocator() throw() {};
allocator(allocator const&) throw() {};
~allocator() throw() {};

template <typename U>
allocator(allocator<U> const&) throw() {};
//address
pointer address(reference r) const { return &r; };
const_pointer address(const_reference r) const { return &r; };

//memory allocation / deallocation
pointer allocate(size_type cnt, void const * = 0); //Custom
allocation here

void deallocate(pointer p, size_type cnt) throw(); //Custom
deallocation here
//size
size_type max_size() const throw();

//object construction / destrucion
void construct(pointer p, T const& t) const { new (p) T(t); };
void destroy(pointer p) const throw() { p->~T(); };
bool operator == (allocator const&) { return true; };
bool operator != (allocator const& a) { return false; };

};


Gr*****@nospam.com wrote:
Is it safe to do that ? I mean, I'm using custom iterators for legacy
containers already and I need my version of new and delete to be called
by STL algorithms (which already use my custom Iterators).

i.e. I am going to be using stl algorithms with custom containers and
it's essential that our version of new and delete be called. Fair
enough, if yes, just wanted to check.

thanks

G


Nov 22 '05 #5

P: n/a
Mark P wrote:
Gr*****@nospam.com wrote:
Is it safe to do that ? I mean, I'm using custom iterators for legacy
containers already and I need my version of new and delete to be called
by STL algorithms (which already use my custom Iterators).

i.e. I am going to be using stl algorithms with custom containers and
it's essential that our version of new and delete be called. Fair
enough, if yes, just wanted to check.

thanks

G


Actually, my recollection/experience is that STL containers will use
placement new rather than "regular" operator new.


Ok, I am getting in a field I don't know. I never worked much with
custom allocators or overloading new and delete, so I'll make some
guesses and leave others to respond.

The standard explictly states that std::allocator::construct() has the
effect of
"new((void*)p) T(t)", which clearly does not explicitly use global new
operator. That means it should use placement new defined for a class.
However, the compiler I use (VS 2005) has "::new (p) T(v);" instead,
but I think it is illegal.

Concerning allocate() and deallocate(), I found nothing in the standard
stating whether the operators used are global or not, but Josuttis says
"The default allocator uses the global operators new and delete to
allocate and deallocate memory". So that probably rules out overloaded
operators.

So finally, I think you *will* need to provide your own allocator. You
may have a look at http://www.open-std.org/jtc1/sc22/open/n2356/. It is
the 1997 draft C++ standard. Particularily, 20.1.5 describes
requirements and 20.4.1 describes the class interface. Josuttis' "The
C++ Standard Library" also does a good job explaining allocators and I
think I remember reading something in TCPPPL.

Hope this helps,
Jonathan

Nov 22 '05 #6

P: n/a
Andy Venikov wrote:
The standard containers won't ever call new to allocate memory -
they'll use
allocator supplied with template instantiation and placement new to
invoke
the constructor.


The default allocator uses operator new to get memory for storing
objects. It then uses placement new, as appropriate, to construct
objects in the memory that it got.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Nov 22 '05 #7

P: n/a
Sorry, let me refrase:

The standard containers won't call new DIRECTLY to allocate memory.
If new is getting called, then only through the allocation policy
supplied to the container. And I think that's what the OP wanted.

Thanks,
Andy.

Nov 22 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.