"Dmitriy V'jukov" <dvyukov@[EMAIL PROTECTED]
> wrote in message
news:aabd7f24-429e-4276-bbcc->
790bbc4959b2@[EMAIL PROTECTED]
> On Oct 2, 10:50 pm, "Chris M. Thomasson" <n...@[EMAIL PROTECTED]
> wrote:
>
> > Please correct me if I am wrong, but it seems as if this particular
> > allocator interface would "need" to know what type it was dealing with
> > in
> > advance; correct?
>
> Yes,
>
> > In other words, it probably could not be used to overload
> > global operator new/delete right?
> Yes.
> > Or, is `derived_t' dealing with internal
> > allocator structures. Where am I going wrong here Dmitriy? You know, I
> > was
> > thinking about creating something special for C++. But, I am a C
> > programmer,
> > and felt the need to sup****t my language of choice. The cool thing
about
> > C++
> > is that you can do exactly what you did. Also, you can overload class
> > local
> > delete operator and have it automatically return the size of the
dynamic
> > allocation be it single object or array. If the user allocated an
array,
> > you
> > simply divide this size of object size, and bam you have array size.
> It's not always true. For example:
> template<typename derived_t>
> struct object_t
> {
> static void* operator new (size_t sz)
> {
> return malloc(sizeof(derived_t));
> }
> };
> struct derived1 : object_t<derived1>
> {
> int x1;
> };
> struct derived2 : derived1
> {
> int x2;
> };
> derived2* d2 = new derived2 (); // CRASH! Allocate memory only for
> derived1, derived2 will not fit into that memory
Well, apparently I find bug in GCC, or work around... Try this:
template<typename derived_t>
struct object_t
{
static void* operator new (size_t sz)
{
return malloc(sizeof(derived_t));
}
};
struct derived1 : object_t<derived1>
{
int x1;
};
struct derived2 : public derived1, public object_t<derived2>
{
int x2;
};
Here is full blown example code that compiles with GCC and MSVC:
______________________________________________________________
#include <cstdio>
#include <cstdlib>
#include <new>
struct custom_allocator {
static void* allocate(std::size_t size)
throw(std::bad_alloc()) {
void* const mem = ::operator new(size);
std::printf("custom_allocator::allocate(%p, %lu)\n",
(void*)mem, (unsigned long)size);
return mem;
}
static void deallocate(void* const mem, std::size_t size)
throw() {
std::printf("custom_allocator::deallocate(%p, %lu)\n",
(void*)mem, (unsigned long)size);
::operator delete(mem);
}
};
template<typename T>
struct allocator_base {
static void* operator new(std::size_t size)
throw(std::bad_alloc()) {
return custom_allocator::allocate(size);
}
static void* operator new[](std::size_t size)
throw(std::bad_alloc()) {
return custom_allocator::allocate(size);
}
static void operator delete(void* mem)
throw() {
if (mem) {
custom_allocator::deallocate(mem, sizeof(T));
}
}
static void operator delete [](void* mem, std::size_t size)
throw() {
if (mem) {
custom_allocator::deallocate(mem, size);
}
}
};
template<std::size_t T_size>
class buf {
char mem[T_size];
};
class buf2 : public buf<1234>, public allocator_base<buf2> {
char mem2[1000];
};
int main() {
buf2* b = new buf2;
delete b;
b = new buf2[5];
delete [] b;
return 0;
}
______________________________________________________________
Here is output I get:
custom_allocator::allocate(00246C50, 2234)
custom_allocator::deallocate(00246C50, 2234)
custom_allocator::allocate(00247760, 11174)
custom_allocator::deallocate(00247760, 11174)
Work around or UB? Well, it seems that it is 100% UB because the output I
get on MSVC 8 is:
custom_allocator::allocate(00362850, 2234)
custom_allocator::deallocate(00362850, 2234)
custom_allocator::allocate(00366B68, 11170)
custom_allocator::deallocate(00366B68, 2234)
WTF? No wonder I am a C guy!!!!
;^/


|