'placement' new, and allocation in the constructor.

S

Shea Martin

If I have a class Foo like this:

class Foo
{
public:
Foo()
{
mData = new char[ time() % 1000 ];
}
~Foo()
{
delete [] mData;
}
private:
char* mData;
};

Now if I create a Foo object using the 'placement' new like so:
void* raw = malloc( sizeof(Foo()) );
Foo *foo = new(raw) Foo();

foo.mData will not be taken from my memory pool, correct? There is no
way to know that how much memory Foo() will allocate. But it *would* be
nice to have the mData memory in the same pool as my foo object.

Any tips or tricks that I am overlooking, that would allow me to do this
(without access to the Foo class)?

Thanks,
~S
 
V

Victor Bazarov

Shea said:
If I have a class Foo like this:

class Foo
{
public:
Foo()
{
mData = new char[ time() % 1000 ];
}
~Foo()
{
delete [] mData;
}
private:
char* mData;
};

Now if I create a Foo object using the 'placement' new like so:
void* raw = malloc( sizeof(Foo()) );
Foo *foo = new(raw) Foo();

foo.mData will not be taken from my memory pool, correct?

Which one is "your" memory pool? Essentially both 'malloc' and 'new'
(or 'new[]') perform allocations in what is known as "free store". For
all we know, it's one and the same "memory pool" for both of them.
There is no
way to know that how much memory Foo() will allocate. But it *would*
be nice to have the mData memory in the same pool as my foo object.

Would it? Really? Why?
Any tips or tricks that I am overlooking, that would allow me to do
this (without access to the Foo class)?

You _could_ provide your own 'malloc' and 'new[]'. If you know for sure
that 'Foo' uses "new[]", then you just need to overload the function
called '::eek:perator new[]' and do what you need there.

V
 
S

Shea Martin

Victor said:
Which one is "your" memory pool? Essentially both 'malloc' and 'new'
(or 'new[]') perform allocations in what is known as "free store". For
all we know, it's one and the same "memory pool" for both of them.
Really? You have no idea what I am talking about when I say my memory
pool? While you are correct, I didn't explicitly state that 'my memory
pool' is a chuck of memory, somewhere other than the free store, but
most people probably connected the dots on their own. IMHO, you
probably did too, but because you are an elitist, you chose to be sarcastic.
Would it? Really? Why?
When working with a finite amount of memory, and no virtual memory, it
helps to have a memory budget. Especially when there are different
groups working on different parts of the project. If I allocate memory,
I want only to take away from my pool, if someone in another group
allocates for something, I want their object to only use memory from
their pool. But I'll bet you could have guessed the something like
that, but chose to be a smart arse.

Any tips or tricks that I am overlooking, that would allow me to do
this (without access to the Foo class)?

You _could_ provide your own 'malloc' and 'new[]'. If you know for sure
that 'Foo' uses "new[]", then you just need to overload the function
called '::eek:perator new[]' and do what you need there.
Thank you. A suggestion that is worth the bytes used to store it. The
problem with overriding the default operator new and malloc, is wouldn't
that force the application to use my new/malloc. This doesn't really
help when have 3 groups all with their own memory budget. Although, it
does help, in that I could perform some logging

~S
 
L

Lyell Haynes

foo.mData will not be taken from my memory pool, correct? There is no
way to know that how much memory Foo() will allocate. But it *would* be
nice to have the mData memory in the same pool as my foo object.

If you don't plan to override global new and delete, you can create a
memory allocator object and pass it to Foo which will tell it how to
allocate memory for it internal objects. If written well, the allocator
can be parameterized to use any number of different allocation
mechanisms - placement new, malloc, some static array of memory, etc.
You would then use the allocator to create object Foo and pass the
allocator to Foo so that it creates internal objects from the same
memory store.

Lyell
 
T

Tom Widmer

Shea said:
You _could_ provide your own 'malloc' and 'new[]'. If you know for sure
that 'Foo' uses "new[]", then you just need to overload the function
called '::eek:perator new[]' and do what you need there.

Thank you. A suggestion that is worth the bytes used to store it. The
problem with overriding the default operator new and malloc, is wouldn't
that force the application to use my new/malloc. This doesn't really
help when have 3 groups all with their own memory budget. Although, it
does help, in that I could perform some logging

You could restrict the overload to a particular module (and put Foo in
its own module), if you use dynamic linking carefully. For example,
under Windows, each DLL can can have its own new and delete, though
obviously the DLL that allocated something must delete it (unless the
allocators use shared state).

Tom
 
M

mlimber

Shea said:
Victor said:
Any tips or tricks that I am overlooking, that would allow me to do
this (without access to the Foo class)?

You _could_ provide your own 'malloc' and 'new[]'. If you know for sure
that 'Foo' uses "new[]", then you just need to overload the function
called '::eek:perator new[]' and do what you need there.
Thank you. A suggestion that is worth the bytes used to store it. The
problem with overriding the default operator new and malloc, is wouldn't
that force the application to use my new/malloc. This doesn't really
help when have 3 groups all with their own memory budget. Although, it
does help, in that I could perform some logging

You could overload the global new (and delete!) operators without
affecting others if you use a different memory pool class for each
group of devlopers. See this FAQ for the outline:

http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.14

and then just extend that by creating three classes (Pool1, Pool2, and
Pool3 or whatever) and three overloads of new and delete.

Cheers! --M
 
S

Shea Martin

Lyell said:
If you don't plan to override global new and delete, you can create a
memory allocator object and pass it to Foo which will tell it how to
allocate memory for it internal objects. If written well, the allocator
can be parameterized to use any number of different allocation
mechanisms - placement new, malloc, some static array of memory, etc.
You would then use the allocator to create object Foo and pass the
allocator to Foo so that it creates internal objects from the same
memory store.

Lyell

I considered this. The con is that I don't always have access to the
source for Foo. The plus, is that it makes it obvious what is going on
in the code.

~S
 
S

Shea Martin

Tom said:
Shea said:
You _could_ provide your own 'malloc' and 'new[]'. If you know for sure
that 'Foo' uses "new[]", then you just need to overload the function
called '::eek:perator new[]' and do what you need there.

Thank you. A suggestion that is worth the bytes used to store it.
The problem with overriding the default operator new and malloc, is
wouldn't that force the application to use my new/malloc. This
doesn't really help when have 3 groups all with their own memory
budget. Although, it does help, in that I could perform some logging

You could restrict the overload to a particular module (and put Foo in
its own module), if you use dynamic linking carefully. For example,
under Windows, each DLL can can have its own new and delete, though
obviously the DLL that allocated something must delete it (unless the
allocators use shared state).

Tom

This sounds almost perfect. I'll have to get on the OS boards to see if
this is supported on other platforms.

~S
 
S

Shea Martin

mlimber said:
Shea said:
Victor said:
Any tips or tricks that I am overlooking, that would allow me to do
this (without access to the Foo class)?
You _could_ provide your own 'malloc' and 'new[]'. If you know for sure
that 'Foo' uses "new[]", then you just need to overload the function
called '::eek:perator new[]' and do what you need there.
Thank you. A suggestion that is worth the bytes used to store it. The
problem with overriding the default operator new and malloc, is wouldn't
that force the application to use my new/malloc. This doesn't really
help when have 3 groups all with their own memory budget. Although, it
does help, in that I could perform some logging

You could overload the global new (and delete!) operators without
affecting others if you use a different memory pool class for each
group of devlopers. See this FAQ for the outline:

http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.14

and then just extend that by creating three classes (Pool1, Pool2, and
Pool3 or whatever) and three overloads of new and delete.

Cheers! --M

I think I am missing something here. I have already read this FAQ, it
is what raised my original question.

so if I create:
operator new( size_t nbytes, PoolA& pool )
operator new( size_t nbytes, PoolB& pool )
operator new( size_t nbytes, PoolC& pool ).

Then lets say I create an object Foo.
new( pool_a ) Foo();

Now what makes the memory that is allocated from foo come from pool_a?
Even if I do reimplement the default operator new, I won't have any idea
that when Foo uses it to allocate for mData, that it should come from
pool_a.

~S
 
M

mlimber

Shea said:
mlimber said:
Shea said:
Victor Bazarov wrote:
Any tips or tricks that I am overlooking, that would allow me to do
this (without access to the Foo class)?
You _could_ provide your own 'malloc' and 'new[]'. If you know for sure
that 'Foo' uses "new[]", then you just need to overload the function
called '::eek:perator new[]' and do what you need there.
Thank you. A suggestion that is worth the bytes used to store it. The
problem with overriding the default operator new and malloc, is wouldn't
that force the application to use my new/malloc. This doesn't really
help when have 3 groups all with their own memory budget. Although, it
does help, in that I could perform some logging

You could overload the global new (and delete!) operators without
affecting others if you use a different memory pool class for each
group of devlopers. See this FAQ for the outline:

http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.14

and then just extend that by creating three classes (Pool1, Pool2, and
Pool3 or whatever) and three overloads of new and delete.

Cheers! --M

I think I am missing something here. I have already read this FAQ, it
is what raised my original question.

so if I create:
operator new( size_t nbytes, PoolA& pool )
operator new( size_t nbytes, PoolB& pool )
operator new( size_t nbytes, PoolC& pool ).

Then lets say I create an object Foo.
new( pool_a ) Foo();

Now what makes the memory that is allocated from foo come from pool_a?
Even if I do reimplement the default operator new, I won't have any idea
that when Foo uses it to allocate for mData, that it should come from
pool_a.

~S

Well, I was only dealing with the part that I quoted, viz. the part
about overloading (n.b., not overriding, i.e. replacing) the global new
and delete. To have Foo internally allocate memory from the same pool,
you'd need to setup an allocator scheme like in the STL that also uses
your pools, as suggested by another respondent.

Cheers! --M
 
M

mlimber

mlimber said:
To have Foo internally allocate memory from the same pool,
you'd need to setup an allocator scheme like in the STL that also uses
your pools, as suggested by another respondent.

The reply above assumes you require that the different developer teams
need to use the same class with different pools. If you alone need Foo,
then you can use a global/singleton pool object or pass the proper pool
object to Foo in its constructor and use that whenever you allocate
memory internally.

Cheers! --M
 

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,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top