Obj* ptr = new Obj(X)

P

Phil Endecott

Dear All,

I'm experimenting with a class that allocates itself using a nonstandard
allocator:

class Obj {
public:

static void* operator new (size_t sz) {
return my_allocate(sz);
}
static void* operator new[] (size_t sz) {
return my_allocate(sz);
}
static void operator delete (void* p, size_t sz) {
my_deallocate(p, sz);
}
static void operator delete[] (void* p, size_t sz) {
my_deallocate(p, sz);
}
... etc ...
};

This works fine for simple cases, but I am not sure how to deal with
this use of new:

Obj* ptr = new Obj(X)

I believe that this should allocate a new Obj and invoke its
copy-constructor to initialise it with a copy of X. I think that, in
order to support this, I need to implement

static void* operator new (size_t sz, const Obj& o)

Is this right? So, what should this function do? Maybe

obj* p = my_allocate(sz);
*p = o;
return p;

But this seems all wrong. Surely the purpose of operator new is to
allocate the memory, with construction happening later. And what about
subclasses of Obj?

I think I am missing something basic here - can someone help me out?

Cheers, --Phil.
 
J

John Carson

Phil Endecott said:
Dear All,

I'm experimenting with a class that allocates itself using a
nonstandard allocator:
[snip]

This works fine for simple cases, but I am not sure how to deal with
this use of new:

Obj* ptr = new Obj(X)

I believe that this should allocate a new Obj and invoke its
copy-constructor to initialise it with a copy of X. I think that, in
order to support this, I need to implement

static void* operator new (size_t sz, const Obj& o)

Is this right?
No.

So, what should this function do? Maybe

obj* p = my_allocate(sz);
*p = o;
return p;

But this seems all wrong. Surely the purpose of operator new is to
allocate the memory, with construction happening later. And what about
subclasses of Obj?

I think I am missing something basic here - can someone help me out?

Any user-defined operator new is responsible solely for memory allocation.
Constructor calls will be handled by the compiler, just as if you were using
the standard operator new.
 
P

Phil Endecott

John said:
Phil Endecott wrote
No.
Any user-defined operator new is responsible solely for memory allocation.
Constructor calls will be handled by the compiler, just as if you were
using the standard operator new.

Thanks John. That makes sense.

I found myself thinking the wrong way because of an error message:

/usr/include/c++/3.3/bits/stl_construct.h:78: error: no matching
function for
call to `shm_vec_char::eek:perator new(unsigned int, void*&)'
.../apachemod/shm_alloc.h:278: error: candidates are: static void*
Shm::Obj::eek:perator new(unsigned int)

I am trying to store these things in a std::vector, and there is more
going on than I have explained. I'll post again if I can come up with a
sufficiently simple example.

--Phil.
 
M

Mark P

Phil said:
Thanks John. That makes sense.

I found myself thinking the wrong way because of an error message:

/usr/include/c++/3.3/bits/stl_construct.h:78: error: no matching
function for
call to `shm_vec_char::eek:perator new(unsigned int, void*&)'
../apachemod/shm_alloc.h:278: error: candidates are: static void*
Shm::Obj::eek:perator new(unsigned int)

I am trying to store these things in a std::vector, and there is more
going on than I have explained. I'll post again if I can come up with a
sufficiently simple example.

--Phil.

I believe it's more complicated if you want to store your objects in an
STL class.

If you just store pointers nothing really special happens, but since STL
classes own their objects and allocate memory for them via their own
allocator objects, it's unlikely that your operator new will ever be
called.

Instead I think STL classes will invoke placement new after allocating
the memory themselves. This is in fact what your error message
indicates-- notice the function it's looking for looks like: operator
new(unsigned int, void*). The unsigned int is size_t on your system,
and the void* is the location for the new object.

By defining your own operator new you hide the global placement new.
Try adding:

void* operator new(size_t size, void* loc) {return ::eek:perator
new(size,loc);}

to your class definition, which will restore access to global placement new.

Hope that helps,
Mark
 
P

Phil Endecott

Mark said:
By defining your own operator new you hide the global placement new. Try
adding:

void* operator new(size_t size, void* loc) {return ::eek:perator
new(size,loc);}

Thanks! I didn't know it would be hidden.
I presume I also need a version for new[] :

void* operator new[] (size_t size, void* loc) {
return ::eek:perator new[](size,loc);
}

--Phil.
 
M

Mark P

Phil said:
Mark said:
By defining your own operator new you hide the global placement new.
Try adding:

void* operator new(size_t size, void* loc) {return ::eek:perator
new(size,loc);}


Thanks! I didn't know it would be hidden.
I presume I also need a version for new[] :

void* operator new[] (size_t size, void* loc) {
return ::eek:perator new[](size,loc);
}

--Phil.

I'm not an expert but I imagine it can't hurt. Not sure how often
placement new[] is actually used though. I don't think I've ever
encountered an STL allocator which attempted to use this.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,565
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top