473,327 Members | 2,112 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,327 software developers and data experts.

Passing address of stack memory to placement new operator

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
15 4611
* 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
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
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
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
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
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
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
* 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
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
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
* 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
* 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
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
* 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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: Philip Lawatsch | last post by:
Hi, I have some questions about whats written in http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.14 (Describing some memory pool) #1 From what i understand this will also work for new...
58
by: jr | last post by:
Sorry for this very dumb question, but I've clearly got a long way to go! Can someone please help me pass an array into a function. Here's a starting point. void TheMainFunc() { // Body of...
17
by: Jonas Rundberg | last post by:
Hi I just started with c++ and I'm a little bit confused where stuff go... Assume we have a class: class test { private: int arr; };
81
by: candy | last post by:
hi all, Is there is any way in the C language by which I can get the address of a statement? For eg,consider the following simple program: 1. #include<stdio.h> 2. 3. int main(void){ 4. ...
11
by: John Pass | last post by:
Hi, In the attached example, I do understand that the references are not changed if an array is passed by Val. What I do not understand is the result of line 99 (If one can find this by line...
9
by: rob.kirkpatrick | last post by:
Hello I need to populate an array of char arrays at run-time. A very simplifed version of the code is below. char ** list should contain cnt char arrays. The values of char ** list are set by...
7
by: shanemh | last post by:
I'm starting out with c++ and for some reason I cant get my brain around this one: If I have the following: void Foo (someClass& x) {} int Main (void) {
5
by: Lagarde Sébastien | last post by:
Hello, I write code to debug new call with following macro: #define new (MemoryManager::Get().setOwner (__FILE__, __LINE__, _FUNCTION-), FALSE) ? NULL : new The setOwner allow to save the...
18
by: sanjay | last post by:
Hi, I have a doubt about passing values to a function accepting string. ====================================== #include <iostream> using namespace std; int main() {
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.