Go Back   Rhinocerus > Newsgroup > Newsgroup comp.language.c++ > Newsgroup comp.language.c++.moderated

Reply
 
Thread Tools Display Modes
  #1 (permalink)  
Old 10-27-2005, 03:20 PM
Oliver S.
Guest
 
Posts: n/a
Default My lallocator<T>


I was often annoyed about the performance of std::basic-string because
of complex memory-allocators working in the background to found the work
of std::allocator<T>. Basically, the performance doesn't reeach the per-
formance of a stack-based C-string in most cases. But nevertheless, the
comfort and the implicit protection against buffer-overflows makes std::
basic_string woth to be used. So I searched for a way to have my own
stack-based memory-allocation. I came up with the following idea which
resulted in a class I called the lallocator (derived from local alloca-
tor; this sounds funny in german because to "lall" means to babble in
german *g*).
First, we have the lallocator-class which is an interface to the locally
allocated storage for the stl-object (my lallocator can't be used for
strings only). This class is the same for all sizes of local stack-based
pools to prevent that we would compile derived stl-classes for any size
we use. Second, there's a class called lallocator_buffer_if which is the
interface to the local storage we allocated for the lallocator. I defined
this interface for all sizes of locally allocated pools to prevent any
secial-buffer-size-compiling I mentioned before. Third there's a dervied
class of lallocator_buffer_if<T>, called lallocator_buffer<T, buffers,
size>; T is the usual data-type in the buffers, buffers is the number of
buffers which can be allocated by the lallocator and size is the size of
each buffer. Whenever someone tries to do an allocate() on the lallocator
and there's a free buffer and the buffer is large enough to satisfy the
allocation-request, we'll allocate the buffer from the pool; otherwise
we fall back to std::allocator.

Here's an example of how this is used:

typedef std::basic_string<char, char_traits<char>, lallocator<char> >
lallostring;

lallocator_buffer<char, 5, 128> lbc;
lallocator<char> lallo( &lbc );
lallostring lsTest( lallo );

lsTest = "sdsdass";

Unfortunately my compiler isn't able to eat the following code
to prevent explicit instanciation of a lallocator<T>-object:

lallocator_buffer<char, 5, 128> lbc;
lallostring lsTest( lallocator<char>( &lbc ) );

Does anyone know if there's a conformance-problem here or is this
just a bug of my compiler?


So here's my lalloator (it isn't fully stl-conformant and I used a single
trick to prevent having an additional pointer in lallocator_buffer_if which
causes my code not to work on theoretical C++-implementations; sorry to all
religious developers):



template<typename T>
class lallocator_buffer_if
{
protected:
template<typename T, std::size_t buffers, std::size_t buffer_size>
friend class lallocator_buffer;

template<typename T>
friend class lallocator;

private:
lallocator_buffer_if() {}
T *pop_buffer();
void push_buffer( T *pt );
bool is_yours( T *pt );

protected:
union buffer_header
{
buffer_header *pbhNextFree;
T at[1];
};

protected:
std::size_t m_buffer_size;
buffer_header *m_pbhFirstFree;
buffer_header *m_pbhBufferEnd;
};

template<typename T>
inline
T *lallocator_buffer_if<T>:op_buffer()
{
buffer_header *pbh;

if( (pbh = m_pbhFirstFree) == NULL )
return NULL;

return m_pbhFirstFree = pbh->pbhNextFree,
&pbh->at[0];
}


template<typename T>
inline
void lallocator_buffer_if<T>:ush_buffer( T *pt )
{
buffer_header *pbh;

pbh = (buffer_header *)pt;
pbh->pbhNextFree = m_pbhFirstFree;
m_pbhFirstFree = pbh;
}

template<typename T>
inline
bool lallocator_buffer_if<T>::is_yours( T *pt )
{
return (void*)pt >= (void *)this &&
pt < &m_pbhBufferEnd->at[0];
}



template<typename T, std::size_t buffers, std::size_t buffer_size>
class lallocator_buffer : public lallocator_buffer_if<T>
{
public:
lallocator_buffer();

private:
union buffer
{
buffer_header bh;
T atUnReferenced[buffer_size];
};

private:
buffer aBuffers[buffers];
};

template<typename T, std::size_t buffers, std::size_t buffer_size>
inline
lallocator_buffer<T, buffers, buffer_size>::lallocator_buffer()
{
buffer *pbuf,
*pbufNext;

for( (pbuf = &aBuffers[buffers - 1],
pbufNext = NULL);
pbuf >= aBuffers;
(pbufNext = pbuf,
pbuf -= 1) )
pbuf->bh.pbhNextFree = &pbufNext->bh;

m_buffer_size = buffer_size;
m_pbhBufferEnd = &aBuffers[buffers].bh;
m_pbhFirstFree = &aBuffers[0].bh;
}



template<typename T>
class lallocator : public std::allocator<T>
{
public:
lallocator( lallocator_buffer_if<T> *plbi );
lallocator( lallocator const &lc );
~lallocator() {};
pointer allocate( size_type count, void *hint = NULL );
void deallocate( pointer ptr, size_type count );
lallocator &operator =( lallocator const &lc );

public:
template<class Other>
struct rebind
{
typedef lallocator<Other> other;
};

private:
lallocator_buffer_if<T> *m_plbi;
};

template<typename T>
inline
lallocator<T>::lallocator( lallocator_buffer_if<T> *plbi ) :
std::allocator<T>()
{
m_plbi = plbi;
}

template<typename T>
inline
lallocator<T>::lallocator( lallocator const &lc ) :
std::allocator<T>( lc )
{
m_plbi = lc.m_plbi;
}

template<typename T>
inline
typename lallocator<T>:ointer lallocator<T>::allocate( size_type count,
void *hint )
{
T *pt;

if( count > m_plbi->m_buffer_size ||
(pt = m_plbi->pop_buffer()) == NULL )
return std::allocator<T>::allocate( count );

return pt;
}

template<typename T>
inline
void lallocator<T>::deallocate( pointer ptr, size_type count )
{
if( !m_plbi->is_yours( ptr ) )
return (void)std::allocator<T>::deallocate( ptr, count );

m_plbi->push_buffer( ptr );
}

template<typename T>
inline
typename lallocator<T> &lallocator<T>:perator =( lallocator const &lc )
{
return m_plbi = lc.m_plbi,
*this;
}




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

Reply With Quote
Alt Today
Advertising
 
and become member of Rhinocerus
Standard Sponsored Links

  #2 (permalink)  
Old 10-28-2005, 02:35 PM
Greg
Guest
 
Posts: n/a
Default Re: My lallocator<T>


Oliver S. wrote:
> I was often annoyed about the performance of std::basic-string because
> of complex memory-allocators working in the background to found the work
> of std::allocator<T>. Basically, the performance doesn't reeach the per-
> formance of a stack-based C-string in most cases. But nevertheless, the
> comfort and the implicit protection against buffer-overflows makes std::
> basic_string woth to be used. So I searched for a way to have my own
> stack-based memory-allocation. I came up with the following idea which
> resulted in a class I called the lallocator (derived from local alloca-
> tor; this sounds funny in german because to "lall" means to babble in
> german *g*).
> First, we have the lallocator-class which is an interface to the locally
> allocated storage for the stl-object (my lallocator can't be used for
> strings only). This class is the same for all sizes of local stack-based
> pools to prevent that we would compile derived stl-classes for any size
> we use. Second, there's a class called lallocator_buffer_if which is the
> interface to the local storage we allocated for the lallocator. I defined
> this interface for all sizes of locally allocated pools to prevent any
> secial-buffer-size-compiling I mentioned before. Third there's a dervied
> class of lallocator_buffer_if<T>, called lallocator_buffer<T, buffers,
> size>; T is the usual data-type in the buffers, buffers is the number of
> buffers which can be allocated by the lallocator and size is the size of
> each buffer. Whenever someone tries to do an allocate() on the lallocator
> and there's a free buffer and the buffer is large enough to satisfy the
> allocation-request, we'll allocate the buffer from the pool; otherwise
> we fall back to std::allocator.
>
> Here's an example of how this is used:
>
> typedef std::basic_string<char, char_traits<char>, lallocator<char> >
> lallostring;
>
> lallocator_buffer<char, 5, 128> lbc;
> lallocator<char> lallo( &lbc );
> lallostring lsTest( lallo );
>
> lsTest = "sdsdass";
>
> Unfortunately my compiler isn't able to eat the following code
> to prevent explicit instanciation of a lallocator<T>-object:
>
> lallocator_buffer<char, 5, 128> lbc;
> lallostring lsTest( lallocator<char>( &lbc ) );
>
> Does anyone know if there's a conformance-problem here or is this
> just a bug of my compiler?
>
>
> So here's my lalloator (it isn't fully stl-conformant and I used a single
> trick to prevent having an additional pointer in lallocator_buffer_if which
> causes my code not to work on theoretical C++-implementations; sorry to all
> religious developers):
>...


Actually, there is nothing wrong with the union of the buffer and the
pointer to the next free buffer. It follows the standard design for a
memory pool - which is what you have implemented. See boost's "pool"
library for another example of a memory pool.

Memory pools work best for constant sized memory allocations - while
std::string allocations will vary in size. But since std::string often
makes many small allocations, there can still be some benefit from
using a sufficiently large size for the memory pool blocks. An even
more effective optimization would to add a fixed-sized character buffer
data member to the string class itself. By so doing, the performance
for std::strings would equal that of stack-based strings for strings
shorter than a certain length.

Greg


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

Reply With Quote
  #3 (permalink)  
Old 10-28-2005, 02:35 PM
Branimir Maksimovic
Guest
 
Posts: n/a
Default Re: My lallocator<T>


Oliver S. wrote:
> I was often annoyed about the performance of std::basic-string because
> of complex memory-allocators working in the background to found the work
> of std::allocator<T>. Basically, the performance doesn't reeach the per-
> formance of a stack-based C-string in most cases. But nevertheless, the
> comfort and the implicit protection against buffer-overflows makes std::
> basic_string woth to be used. So I searched for a way to have my own
> stack-based memory-allocation. I came up with the following idea which
> resulted in a class I called the lallocator (derived from local alloca-
> tor; this sounds funny in german because to "lall" means to babble in
> german *g*).



>
> Here's an example of how this is used:
>
> typedef std::basic_string<char, char_traits<char>, lallocator<char> >
> lallostring;
>
> lallocator_buffer<char, 5, 128> lbc;
> lallocator<char> lallo( &lbc );
> lallostring lsTest( lallo );
>
> lsTest = "sdsdass";
>
> Unfortunately my compiler isn't able to eat the following code
> to prevent explicit instanciation of a lallocator<T>-object:
>
> lallocator_buffer<char, 5, 128> lbc;
> lallostring lsTest( lallocator<char>( &lbc ) );


Oh, this is just common error you have declared function.


>
> template<typename T>
> class lallocator : public std::allocator<T>
> {
> public:
> lallocator( lallocator_buffer_if<T> *plbi );
> lallocator( lallocator const &lc );
> ~lallocator() {};
> pointer allocate( size_type count, void *hint = NULL );
> void deallocate( pointer ptr, size_type count );
> lallocator &operator =( lallocator const &lc );
>
> public:
> template<class Other>
> struct rebind
> {
> typedef lallocator<Other> other;
> };
>
> private:
> lallocator_buffer_if<T> *m_plbi;
> };
>


This class needs default constructor for rebind purposes.
Ok, after correcting compiler errors here is your code:
you can make static pointer used for default constructor,
into a static thread local storage pointer if needed.
There is alwayspossibility that memory allocated with
one allocator could be freed with other, so you have
to be carefull not to set different buffers in a scope.

#include <string>
#include <cassert>
//using namespace std;


#ifndef __GNUG__
#define __thread /* this_would_be_a_great_thing_to_have */
#endif


template<typename T>
class lallocator_buffer_if
{
protected:
template<typename TT, std::size_t buffers, std::size_t buffer_size>
friend class lallocator_buffer;

template<typename TT>
friend class lallocator;

private:
lallocator_buffer_if() {}
T *pop_buffer();
void push_buffer( T *pt );
bool is_yours( T *pt );

protected:
union buffer_header
{
buffer_header *pbhNextFree;
T at[1];
};

protected:
std::size_t m_buffer_size;
buffer_header *m_pbhFirstFree;
buffer_header *m_pbhBufferEnd;

};

template<typename T>
inline
T *lallocator_buffer_if<T>:op_buffer()
{
buffer_header *pbh;

if( (pbh = m_pbhFirstFree) == NULL )
return NULL;

return m_pbhFirstFree = pbh->pbhNextFree,
&pbh->at[0];

}

template<typename T>
inline
void lallocator_buffer_if<T>:ush_buffer( T *pt )
{
buffer_header *pbh;

pbh = (buffer_header *)pt;
pbh->pbhNextFree = m_pbhFirstFree;
m_pbhFirstFree = pbh;

}

template<typename T>
inline
bool lallocator_buffer_if<T>::is_yours( T *pt )
{
return (void*)pt >= (void *)this &&
pt < &m_pbhBufferEnd->at[0];

}

template<typename T, std::size_t buffers, std::size_t buffer_size>
class lallocator_buffer : public lallocator_buffer_if<T>
{
public:
lallocator_buffer();

private:
union buffer
{
typename lallocator_buffer_if<T>::buffer_header bh;
T atUnReferenced[buffer_size];
};

private:
buffer aBuffers[buffers];

};

template<typename T, std::size_t buffers, std::size_t buffer_size>
inline
lallocator_buffer<T, buffers, buffer_size>::lallocator_buffer()
{
buffer *pbuf,
*pbufNext;

for( (pbuf = &aBuffers[buffers - 1],
pbufNext = NULL);
pbuf >= aBuffers;
(pbufNext = pbuf,
pbuf -= 1) )
pbuf->bh.pbhNextFree = &pbufNext->bh;

this->m_buffer_size = buffer_size;
this->m_pbhBufferEnd = &aBuffers[buffers].bh;
this->m_pbhFirstFree = &aBuffers[0].bh;

}

template<typename T>
class lallocator : public std::allocator<T>
{
public:
typedef typename std::allocator<T>:ointer pointer;
typedef typename std::allocator<T>::size_type size_type;
lallocator():m_plbi(m_buffer) { assert(m_plbi); }
lallocator( lallocator_buffer_if<T> *plbi );
lallocator( lallocator const &lc );
~lallocator() {};
pointer allocate(size_type count, void *hint = NULL );
void deallocate( pointer ptr, size_type count );
lallocator &operator =( lallocator const &lc );

static void set_buffer(lallocator_buffer_if<T>* b)
{
m_buffer=b;
}

public:
template<class Other>
struct rebind
{
typedef lallocator<Other> other;
};

private:
lallocator_buffer_if<T> *m_plbi;
static __thread lallocator_buffer_if<T>* m_buffer;
};

template <typename T>
__thread lallocator_buffer_if<T>* lallocator<T>::m_buffer=0;

template<typename T>
inline
lallocator<T>::lallocator( lallocator_buffer_if<T> *plbi ):
std::allocator<T>()
{
m_plbi = plbi;

}

template<typename T>
inline
lallocator<T>::lallocator( lallocator const &lc ) :
std::allocator<T>( lc )
{
m_plbi = lc.m_plbi;

}

template<typename T>
inline
typename lallocator<T>:ointer lallocator<T>::allocate( size_type
count, void *hint )
{
T *pt;

if( count > m_plbi->m_buffer_size ||
(pt = m_plbi->pop_buffer()) == NULL )
return std::allocator<T>::allocate( count );

return pt;

}

template<typename T>
inline
void lallocator<T>::deallocate( pointer ptr, size_type count )
{
if( !m_plbi->is_yours( ptr ) )
return (void)std::allocator<T>::deallocate( ptr, count );

m_plbi->push_buffer( ptr );

}

template<typename T>
inline
lallocator<T>& lallocator<T>:perator =( lallocator<T> const &lc )
{
return m_plbi = lc.m_plbi,
*this;

}

int main()
{
typedef std::basic_string<char, std::char_traits<char>,
lallocator<char> >
lallostring;

lallocator_buffer<char, 5, 128> lbc;
lallocator<char> lallo( &lbc );
lallocator<char>::set_buffer(&lbc);
lallostring lsTest( lallo );

lsTest = "sdsdass";
{
lallocator_buffer<char, 5, 128> lbc;
lallocator<char>::set_buffer(&lbc);
lallostring lsTest ((lallocator<char>( &lbc
)));
lsTest+="abc"+lallostring("def");
}
}

Greetings, Bane.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

Reply With Quote
  #4 (permalink)  
Old 10-28-2005, 02:35 PM
kuyper@wizard.net
Guest
 
Posts: n/a
Default Re: My lallocator<T>


Oliver S. wrote:
...
> Unfortunately my compiler isn't able to eat the following code


That isn't very specific. It would help a great deal if you indicated
what, precisely, your compiler said was indigestible about this code.

...
> So here's my lalloator (it isn't fully stl-conformant and I used a single
> trick to prevent having an additional pointer in lallocator_buffer_if which
> causes my code not to work on theoretical C++-implementations; sorry to all
> religious developers):


Your use of the words "theoretical" and "religious" implies that you
think the non-conformance is unimportant. It might be; but you should
seriously consider the possibility that the problems you're having may
in fact be due to that non-conformance. In particular, implementations
are allowed to assume that all instances of a given allocator type are
equivalent (20.1.5p4), which isn't the case for your allocators. While
the standard encourages implementators to create implementations that
don't rely on that assumption, many of them do in fact take advantage
of that option, for instance by not actually copying allocators when
they have the same type.

std::list<T,Allocator>::splice() is particularly difficult to implement
efficiently unless you build in an assumption that all instances of
Allocator are equivalent.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

Reply With Quote
  #5 (permalink)  
Old 10-28-2005, 04:28 PM
Maxim Yegorushkin
Guest
 
Posts: n/a
Default Re: My lallocator<T>


Oliver S. wrote:

[]


>> Unfortunately my compiler isn't able to eat the following code
>> to prevent explicit instanciation of a lallocator<T>-object:
>>
>> lallocator_buffer<char, 5, 128> lbc;
>> lallostring lsTest( lallocator<char>( &lbc ) );
>>
>> Does anyone know if there's a conformance-problem here or is this
>> just a bug of my compiler?



You could try putting additional parenthesis like this:

lallostring lsTest( ( lallocator<char>( &lbc ) ) );


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

Reply With Quote
  #6 (permalink)  
Old 10-30-2005, 05:24 PM
Lance Diduck
Guest
 
Posts: n/a
Default Re: My lallocator<T>


Oliver S. wrote:
>> Does anyone know if there's a conformance-problem here or is this

> just a bug of my compiler?


In this paper on Using Stateful Allocator with the STL there is some
code that I've used on a number of platforms, with all the major STL
versions http://www.lancediduck.com/papers/Cpp/StatefulSTL.pdf


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Reply With Quote
  #7 (permalink)  
Old 10-30-2005, 05:24 PM
Oliver S.
Guest
 
Posts: n/a
Default Re: My lallocator<T>


> Actually, there is nothing wrong with the union of the buffer and the
> pointer to the next free buffer. ...


That's not the in-conformance I thought about. Look at is_yours in the
base-class and you can find this in-conformance which might offense some
religious C++ers.

> Memory pools work best for constant sized memory allocations ...


Mine does work equally good for everything up to the limit for a buffer.

> An even more effective optimization would to add a fixed-sized character
> buffer data member to the string class itself.


Maybe, but this wouldn't be a genral-purpose-string anymore because
every string would carry around a buffer that might not be used.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Reply With Quote
  #8 (permalink)  
Old 10-31-2005, 04:04 PM
Oliver S.
Guest
 
Posts: n/a
Default Re: My lallocator<T>


> In this paper on Using Stateful Allocator with the STL there is some
> code that I've used on a number of platforms, with all the major STL
> versions ...


Nearly the same idea, but very low-levelish in your flavour.
I think mine is a bit more comfortable.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

Reply With Quote
  #9 (permalink)  
Old 10-31-2005, 04:04 PM
Oliver S.
Guest
 
Posts: n/a
Default Re: My lallocator<T>


> While the standard encourages implementators to create implementations
> that don't rely on that assumption, many of them do in fact take advantage
> of that option, for instance by not actually copying allocators when
> they have the same type.


I intentionally missed a default-constructor to prevent that and thereby
enforce a compilation-error.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

Reply With Quote
  #10 (permalink)  
Old 10-31-2005, 04:05 PM
Oliver S.
Guest
 
Posts: n/a
Default Re: My lallocator<T>


> You could try putting additional parenthesis like this:
>
> lallostring lsTest( ( lallocator<char>( &lbc ) ) );


Thanks, but that doesn't help!

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

Reply With Quote
  #11 (permalink)  
Old 11-01-2005, 03:00 PM
kuyper@wizard.net
Guest
 
Posts: n/a
Default Re: My lallocator<T>


Oliver S. wrote:
> > Actually, there is nothing wrong with the union of the buffer and the
> > pointer to the next free buffer. ...

>
> That's not the in-conformance I thought about. Look at is_yours in the
> base-class and you can find this in-conformance which might offense some
> religious C++ers.


I'm not sure I follow that; in what sense is it non-conformant? I'm
sure it will be obvious two minutes after I post this message, but
right now it isn't.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Reply With Quote
  #12 (permalink)  
Old 11-01-2005, 03:00 PM
Greg Herlihy
Guest
 
Posts: n/a
Default Re: My lallocator<T>


Oliver S. wrote:
> > Actually, there is nothing wrong with the union of the buffer and the
> > pointer to the next free buffer. ...

>
> That's not the in-conformance I thought about. Look at is_yours in the
> base-class and you can find this in-conformance which might offense some
> religious C++ers.


I'm not sure why is_yours() compares the pointer against the pointer to
the buffer. Comparing it against the first item in the buffer's array
would certainly be a valid test:

template<typename T>
inline
bool lallocator_buffer_if<T>::is_yours( T *pt )
{
return pt >= &at[0] and pt < &m_pbhBufferEnd->at[0];
}

> > Memory pools work best for constant sized memory allocations ...

>
> Mine does work equally good for everything up to the limit for a buffer.


Using fixed sized memory blocks to speed up variably-sized allocations
has two principal shortcomings: oversized allocations see no benefit,
while undersized allocations waste memory.

> > An even more effective optimization would to add a fixed-sized character
> > buffer data member to the string class itself.

>
> Maybe, but this wouldn't be a genral-purpose-string anymore because
> every string would carry around a buffer that might not be used.


The string with an internal character buffer would still be general
purpose - oversized strings would continue to allocate their character
buffer dynamically. An unused internal character buffer wastes no more
memory than the memory wasted by deallocated a fixed-sized buffer.
After all, deallocated buffers are never really "freed" (that is,
returned to the general memory pool where it can be used to fulfill any
subsequent memory allocation request). Rather freed buffers are held in
reserve just in case a future string allocation could use it. A string
with an internal buffer on the other hand, returns the buffer to the
general purpose memory pool (or the stack) upon its destruction.

A further advantage that an internal character buffer has over external
storage is that it adds no meaningful delay when constructing or
copying a string object. The entire internal character buffer does not
need to be initialized or copied with the string, just the portion that
contains the string's characters.

Greg


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Reply With Quote
  #13 (permalink)  
Old 11-03-2005, 12:04 PM
Oliver S.
Guest
 
Posts: n/a
Default Re: My lallocator<T>

>> lallocator_buffer<char, 5, 128> lbc;
>> lallostring lsTest( lallocator<char>( &lbc ) );


> Oh, this is just common error you have declared function.


Ok, these seem to have priority over variable-definitions.

> This class needs default constructor for rebind purposes.


I won't supply a default-constructor because I want the STL-classes used with
my lallocator<T> to work with the pools attached to the allocator-objects. The
allocator-objects usually stored internally in the STL-container-classes are
typically rebind'ed versions of the supplied allocator-type to allow for the
allocators supplied to the constructor of the stl-container to be of a dif-
ferent type. These allocator-objects are created through a copy-constructor
I supply. As the major STL-implementations are prepared for stateful alloca-
tors as far as possible, this works.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
 
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off




All times are GMT. The time now is 03:37 PM.


Copyright ©2009

LinkBacks Enabled by vBSEO 3.3.0 RC2 © 2009, Crawlability, Inc.