Sometimes, I need to use placement new instead of new (i.e. just run the constructor without allocating memory). Here's a simple example:
1 2 3 4 5 6 7
/* Allocation */
void *buf_for_obj = my_mempool_alloc(some_size);
A *a = new (buf_for_obj) A;
/* Deletion */
a->~A();
my_mempool_free(buf_for_obj);
This is easy, but usually, I release the object later:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
void alloc_me()
{
void *buf_for_obj = my_mempool_alloc(blah blah);
A *a = new (buf_for_obj) A;
func(a, some_callback);
}
void some_callback(void *data)
{
A *a = (A *)data;
a->~A();
/* Now I need the buffer to be released with my_mempool_free :( */
}
A very ugly solution is to have a void * member in 'A' that will hold the original buffer pointer:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
void alloc_me()
{
void *buf_for_obj = my_mempool_alloc(blah blah);
A *a = new (buf_for_obj) A;
a->orig_buf = buf_for_obj;
func(a, some_callback);
}
void some_callback(void *data)
{
A *a = (A *)data;
void *buf = a->orig_buf;
a->~A();
my_mempool_free(buf);
}
BTW - doing something like void *buf = a in some_callback does not work. Do you have a better idea?
I don't get the problem. The place where A was *IS* the place that was returned from my_mempool_alloc! Placement new just uses the passed place and create an object on that spot, so of course, the pointer to A will be exactly the pointer to the memory location allocated.
1 2 3 4 5 6 7
void some_callback(void *data)
{
A *a = (A *)data;
a->~A();
my_mempool_free(data);
}
But.. what helios said: Why not use the member function "operator new"? You don't have to get headache about calling the destructor, calling "operator delete" and so on.
When I tried to do something like my_mempool_free(data), the program crashed, so this doesn't work.
This doesn't mean the problem is with the pointer to the memory location.
You could put an assert(buf_for_obj == a); in line 4 on your allocator code to check for this. It really should be the case!
For the operator new - thingie, google for it, I am sure there are tons of explanations all over the net. Basically you implement operator new and delete as member functions of the class A, returning the pointer to the place a should be allocated and then use the normal "new A" and this operator gets called.
Placement new is really only necessary in very rare circumstances and most of these make you want to throw up anyway. ;)