By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,332 Members | 1,414 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,332 IT Pros & Developers. It's quick & easy.

Passing address of stack memory to placement new operator

P: n/a
This code is from c++ faq in section 11 :

void someCode()
{
char memory[sizeof(Fred)];
void* p = memory;
Fred* f = new(p) Fred();
f->~Fred(); // Explicitly call the destructor for the placed
object
}

Here we r passing address of stack memory to new .
New is used to allocate memory on heap . Then how can we pass address
of
stack memory to new operator . It is confusing .

Regards ,
Mangesh .

Jun 30 '06 #1
Share this Question
Share on Google+
15 Replies


P: n/a
* mangesh:
This code is from c++ faq in section 11 :

void someCode()
{
char memory[sizeof(Fred)];
void* p = memory;
Fred* f = new(p) Fred();
Should be

Fred* f = ::new(p) Fred();

f->~Fred(); // Explicitly call the destructor for the placed
object
}

Here we r passing address of stack memory to new .
New is used to allocate memory on heap . Then how can we pass address
of
stack memory to new operator . It is confusing .


The basic placement new operator (there are an infinity of them, but the
basic one from <new>) constructs an object in a specified region of memory.

You shouldn't use it because it's a low-level mechanism to subvert the
ordinary language rules and as such is fraught with dangers, even more
than with casts, e.g., as just one example, here that 'memory' may not
be properly aligned for an object of type 'Fred', and in particular:

* A novice should /never/ use the basic placement new.

Most uses of (the basic) placement new are better expressed using
standard library classes such as std::vector, which do the dangerous
stuff for you, in a safe way, so that you don't even see it.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jun 30 '06 #2

P: n/a
mangesh wrote:
void someCode()
{
char memory[sizeof(Fred)];
void* p = memory;
Fred* f = new(p) Fred();
f->~Fred(); // Explicitly call the destructor for the placed
object
}

Here we r passing address of stack memory to new .
I find it baffling that you can take the time to place weird spaces
around your punctuation, but the three letters in the word "are" are
too much effort in the name of readability when you're asking others to
help you.

Anyway, yes, you're doing a placement-new on a stack-allocated array.
New is used to allocate memory on heap .
Not quite -- it allocates memory on the free store, which may or may
not be implemented in terms of the heap. It may also be overridden by
a custom allocator, which incidentally would likely make use of
placement new.
Then how can we pass address
of
stack memory to new operator . It is confusing .


Because a placement new doesn't allocate memory, it uses memory that
you've allocated for it. That's the entire point. It skips the
allocation step and goes straight to construction. It doesn't care
what part of memory the pointer points to, as long as it can be written
to.

Imagine, for example, implementing a custom allocator for small objects
based on a fixed-size arena allocated as a single chunk. That chunk
might be member data of an allocator class, and could therefore be
stack-allocated. Of course, if the allocator class was instantiated
dynamically, then its member data would live on the free store. Since
either could be the case, it would pose a real problem if the compiler
couldn't handle doing a placement new into stack-allocated memory.

Luke

Jun 30 '06 #3

P: n/a
Hi ,
thanks for reply .
Now in given case is statement " f->~Fred() ; " really needed .
Since memory is on stack it will be automaticaly deleted on exiting
function .

Regards
Mangesh .

Luke Meyers wrote:
mangesh wrote:
void someCode()
{
char memory[sizeof(Fred)];
void* p = memory;
Fred* f = new(p) Fred();
f->~Fred(); // Explicitly call the destructor for the placed
object
}

Here we r passing address of stack memory to new .


I find it baffling that you can take the time to place weird spaces
around your punctuation, but the three letters in the word "are" are
too much effort in the name of readability when you're asking others to
help you.

Anyway, yes, you're doing a placement-new on a stack-allocated array.
New is used to allocate memory on heap .


Not quite -- it allocates memory on the free store, which may or may
not be implemented in terms of the heap. It may also be overridden by
a custom allocator, which incidentally would likely make use of
placement new.
Then how can we pass address
of
stack memory to new operator . It is confusing .


Because a placement new doesn't allocate memory, it uses memory that
you've allocated for it. That's the entire point. It skips the
allocation step and goes straight to construction. It doesn't care
what part of memory the pointer points to, as long as it can be written
to.

Imagine, for example, implementing a custom allocator for small objects
based on a fixed-size arena allocated as a single chunk. That chunk
might be member data of an allocator class, and could therefore be
stack-allocated. Of course, if the allocator class was instantiated
dynamically, then its member data would live on the free store. Since
either could be the case, it would pose a real problem if the compiler
couldn't handle doing a placement new into stack-allocated memory.

Luke


Jun 30 '06 #4

P: n/a
mangesh wrote:
Hi ,
thanks for reply .
Now in given case is statement " f->~Fred() ; " really needed .
Since memory is on stack it will be automaticaly deleted on exiting
function .

Please don't top post.

The memory won't be deleted, it will no longer be usable so any object
created on the stack with placement new will be left in limbo.

That's one reason doing so is a daft idea.

--
Ian Collins.
Jun 30 '06 #5

P: n/a
In message <11**********************@i40g2000cwc.googlegroups .com>,
mangesh <ma************@walla.com> writes

Please don't top-post. I've moved your reply to where it should be.

Luke Meyers wrote:
mangesh wrote:
> void someCode()
> {
> char memory[sizeof(Fred)];
> void* p = memory;
> Fred* f = new(p) Fred();
> f->~Fred(); // Explicitly call the destructor for the placed
> object
> }
>
[big snip]
Hi ,
thanks for reply .
Now in given case is statement " f->~Fred() ; " really needed .
Yes.
Since memory is on stack it will be automaticaly deleted on exiting
function .


No. The memory will be deallocated, but the object's destructor is not
called unless you do so explicitly.

Allocating memory, constructing an object, destroying the object and
freeing the memory are four separate steps.

--
Richard Herring
Jun 30 '06 #6

P: n/a
Alf P. Steinbach posted:

Fred* f = new(p) Fred();


Should be

Fred* f = ::new(p) Fred();


Could you please explain that?
--

Frederick Gotham
Jun 30 '06 #7

P: n/a
mangesh posted:

char memory[sizeof(Fred)];

This array isn't necessarily suitably aligned. You need to make sure it's
suitably aligned by either:

(1) Dynamically allocating it
(2) Using union trickery
(3) Using boost's "align_for" (or whatever it's called)
--

Frederick Gotham
Jun 30 '06 #8

P: n/a
* Frederick Gotham:
Alf P. Steinbach posted:

Fred* f = new(p) Fred();

Should be

Fred* f = ::new(p) Fred();


Could you please explain that?


Unqualified placement new might invoke a custom Fred allocation function
instead of the basic placement new.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jun 30 '06 #9

P: n/a
Alf P. Steinbach posted:
* Frederick Gotham:
Alf P. Steinbach posted:

Fred* f = new(p) Fred();
Should be

Fred* f = ::new(p) Fred();
Could you please explain that?


Unqualified placement new might invoke a custom Fred allocation

function instead of the basic placement new.

When you want to use "placement new", would it be wise to always use:
::new(p) Type();
(I realise it won't make a difference with intrinsic types, but it's
consistent nonetheless for dealing with class types).

--

Frederick Gotham
Jun 30 '06 #10

P: n/a
Alf P. Steinbach wrote:
* Frederick Gotham:
Alf P. Steinbach posted:
Fred* f = new(p) Fred();
Should be

Fred* f = ::new(p) Fred();


Could you please explain that?


Unqualified placement new might invoke a custom Fred allocation function
instead of the basic placement new.


But if there is a custom placement new operator defined for Fred,
presumably it is meant to be used. Leaving it unqualified seems fine to
me.

Cheers! --M

Jun 30 '06 #11

P: n/a
* Frederick Gotham:
Alf P. Steinbach posted:
* Frederick Gotham:
Alf P. Steinbach posted:
> Fred* f = new(p) Fred();
Should be

Fred* f = ::new(p) Fred();
Could you please explain that?

Unqualified placement new might invoke a custom Fred allocation

function
instead of the basic placement new.


When you want to use "placement new", would it be wise to always use:

::new(p) Type();

(I realise it won't make a difference with intrinsic types, but it's
consistent nonetheless for dealing with class types).


Yes, that's good advice when you want the in-place construction
behavior, not a custom allocator: let's update FAQ item [11.10]... ;-)

CC: Marshall Cline

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jun 30 '06 #12

P: n/a
* mlimber:
Alf P. Steinbach wrote:
* Frederick Gotham:
Alf P. Steinbach posted:
> Fred* f = new(p) Fred();
Should be

Fred* f = ::new(p) Fred();
Could you please explain that? Unqualified placement new might invoke a custom Fred allocation function
instead of the basic placement new.


But if there is a custom placement new operator defined for Fred,
presumably it is meant to be used.


Depends what you want. If you want to leave the decision of how to
allocate the memory to class Fred, use 'new'. If you want to take
charge, saying Here Should Be Placement Construction, use '::new'.

Leaving it unqualified seems fine to me.


If you want to leave the choice of allocation scheme to class Fred, yes,
but given that you've declared a buffer to put the object in, how likely
is that?

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jun 30 '06 #13

P: n/a
Alf P. Steinbach wrote:
* mlimber:
Alf P. Steinbach wrote:
* Frederick Gotham:
Alf P. Steinbach posted:
>> Fred* f = new(p) Fred();
> Should be
>
> Fred* f = ::new(p) Fred();
Could you please explain that?
Unqualified placement new might invoke a custom Fred allocation function
instead of the basic placement new.


But if there is a custom placement new operator defined for Fred,
presumably it is meant to be used.


Depends what you want. If you want to leave the decision of how to
allocate the memory to class Fred, use 'new'. If you want to take
charge, saying Here Should Be Placement Construction, use '::new'.


In either case, we're using placement new and allocation is done
outside the new operator itself. (If the custom placement new does
something different, it has changed the semantics of that operator and
is no different than changing the semantics of other overloaded
operators, which is generally considered evil as in FAQ 13.9.)
Leaving it unqualified seems fine to me.


If you want to leave the choice of allocation scheme to class Fred, yes,
but given that you've declared a buffer to put the object in, how likely
is that?


By the same logic I think we could justly say that if we've overridden
the placement new operator for this class, how likely is it that we
want to use the global one? Also, Sutter and Alexandrescu note, "If a
class defines any overload of operator new, it should provide overloads
of all three of plain, in-place, and non-throwing operator new. If you
don't, they'll be hidden and unavailable to users of your class." (_C++
Coding Standards_, Item 46).

Cheers! --M

Jun 30 '06 #14

P: n/a
* mlimber:
Alf P. Steinbach wrote:
* mlimber:
Alf P. Steinbach wrote:
* Frederick Gotham:
> Alf P. Steinbach posted:
>>> Fred* f = new(p) Fred();
>> Should be
>>
>> Fred* f = ::new(p) Fred();
> Could you please explain that?
Unqualified placement new might invoke a custom Fred allocation function
instead of the basic placement new.
But if there is a custom placement new operator defined for Fred,
presumably it is meant to be used. Depends what you want. If you want to leave the decision of how to
allocate the memory to class Fred, use 'new'. If you want to take
charge, saying Here Should Be Placement Construction, use '::new'.


In either case, we're using placement new and allocation is done
outside the new operator itself.


Yes.

(If the custom placement new does
something different, it has changed the semantics of that operator
No (it's a circular argument: assuming that 'new' invokes some standard
semantics for the allocation function, then arguing that if it doesn't
the semantics have been changed, but the only standard semantics is for
'::new').

and
is no different than changing the semantics of other overloaded
operators, which is generally considered evil as in FAQ 13.9.)
Yes.

Leaving it unqualified seems fine to me.

If you want to leave the choice of allocation scheme to class Fred, yes,
but given that you've declared a buffer to put the object in, how likely
is that?


By the same logic I think we could justly say that if we've overridden
the placement new operator for this class,


No.

how likely is it that we want to use the global one?
Very. E.g., consider implementing something like a std::vector. Should
a std::vector<Fred> use Fred's placement allocation function if one is
defined? With MSVC 7.1 it does. With g++ 3.4.4 it doesn't. When that
function is inaccessible the code doesn't compile with MSVC 7.1, and I
don't see accessibility of that function as a requirement for standard
container elements (so I think that compiler is wrong). With g++ 3.4.4
the code compiles (which I think is correct, and anyway, it is IMO how a
properly designed & implemented class should work, no surprises).

Also, Sutter and Alexandrescu note, "If a
class defines any overload of operator new, it should provide overloads
of all three of plain, in-place, and non-throwing operator new. If you
don't, they'll be hidden and unavailable to users of your class." (_C++
Coding Standards_, Item 46).


Yes.

However, blaming the designer of class Fred is just that, assigning
blame: instead one should IMO make sure that there is no blame to
assign, by the simple expedient of using code that does what one wants
regardless of the class in question.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jun 30 '06 #15

P: n/a
Alf P. Steinbach wrote:
* mlimber:
In either case, we're using placement new and allocation is done
outside the new operator itself. [snip]
(If the custom placement new does
something different, it has changed the semantics of that operator


No (it's a circular argument: assuming that 'new' invokes some standard
semantics for the allocation function, then arguing that if it doesn't
the semantics have been changed, but the only standard semantics is for
'::new').


I don't follow you here. Please clarify.
Leaving it unqualified seems fine to me.
If you want to leave the choice of allocation scheme to class Fred, yes,
but given that you've declared a buffer to put the object in, how likely
is that?


By the same logic I think we could justly say that if we've overridden
the placement new operator for this class,


No.


No what? I hadn't even finished my thought yet! :-P
how likely is it that we want to use the global one?


Very. E.g., consider implementing something like a std::vector. Should
a std::vector<Fred> use Fred's placement allocation function if one is
defined? With MSVC 7.1 it does. With g++ 3.4.4 it doesn't. When that
function is inaccessible the code doesn't compile with MSVC 7.1, and I
don't see accessibility of that function as a requirement for standard
container elements (so I think that compiler is wrong). With g++ 3.4.4
the code compiles (which I think is correct, and anyway, it is IMO how a
properly designed & implemented class should work, no surprises).


Sutter and Alexandrescu do note in the same item cited previously that
"you should always avoid hiding in-place new because STL containers use
it extensively." However, it seems to me that this is more of a
quality-of-implementation issue (since having the STL use in-place new
is not required by the standard, right?) or a defect in the standard
(the STL containers should have that requirement).

Cheers! --M

Jun 30 '06 #16

This discussion thread is closed

Replies have been disabled for this discussion.