C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Placement new and destructor
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
dragoncoder
Guest





PostPosted: Wed May 10, 2006 10:21 pm    Post subject: Placement new and destructor Reply with quote



Hello all,

I am reading C++ Primer 3rd edition by Lippman & Lajoie and come across
the following piece of code as an example demostrating the use of
placement new.

Section 8.4.5 (Page 417-418)

#include <iostream>
#include <new>

const int chunk = 16;

class Foo {
public:
int val() { return _val; }
Foo() { _val = 0; }
private:
int _val;
};

char *buf = new char[sizeof (Foo) * chunk];

int main() {
Foo *pb = new (buf) Foo;
if ( pb.val() == 0 )
cout << "new expression worked!" << endl;
delete[] buf;
return 0;
}

Looking at the above code, I feel it is incorrect at 2 places.

1. Since pb is a pointer to a Foo object, the expression inside the if
condition should have been pb->val() instead of pb.val(), okay that may
be a printing mistake.

2. The second error is not a typographical error. I see at no place in
the code the destructor of the Foo object is called. Instead delete[]
buf calls the destructors of 16 char objects which is fine but I feel
there should be a call to Foo's destructor before the delete[] buf.
Shouldn't there be a call to pb->~Foo() before delete[] ?

Please tell me, if I am missing something as this book is rated highly
recommended at accu.org.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
peter koch larsen
Guest





PostPosted: Thu May 11, 2006 1:21 pm    Post subject: Re: Placement new and destructor Reply with quote



dragoncoder skrev:

Quote:
Hello all,

I am reading C++ Primer 3rd edition by Lippman & Lajoie and come across
the following piece of code as an example demostrating the use of
placement new.

I believe that book was one of the first C++ books I read (after
Stroustrups), and I remember it as a very good book. But it does have
flaws!
Quote:

Section 8.4.5 (Page 417-418)

#include <iostream
#include <new

const int chunk = 16;

class Foo {
public:
int val() { return _val; }
Foo() { _val = 0; }
private:
int _val;
};

char *buf = new char[sizeof (Foo) * chunk];

int main() {
Foo *pb = new (buf) Foo;
if ( pb.val() == 0 )
cout << "new expression worked!" << endl;
delete[] buf;
return 0;
}

Looking at the above code, I feel it is incorrect at 2 places.

1. Since pb is a pointer to a Foo object, the expression inside the if
condition should have been pb->val() instead of pb.val(), okay that may
be a printing mistake.
You are correct.

2. The second error is not a typographical error. I see at no place in
the code the destructor of the Foo object is called. Instead delete[]
buf calls the destructors of 16 char objects which is fine but I feel
there should be a call to Foo's destructor before the delete[] buf.
Shouldn't there be a call to pb->~Foo() before delete[] ?

I agree once again. This time it is not a direct error - you don't have
to call destructors. And there is no leak - the buffer is deleted all
right. So perhaps we should forgive Lippman and Lajoie considering that
they aim to demonstrate placement new.

Quote:

Please tell me, if I am missing something as this book is rated highly
recommended at accu.org.

Then probably it is a very good book. No book is without errors and
Lippman and Lajoie are both very knowledgeable - and they are fine
writers.

I have a feeling there might be a third error, however. The character
vector is allocated via new char[]. Is new char guaranteed to allocate
memory that is properly aligned for any datatype? So far as I
understand it, the buffer is only guaranteed to be properly aligned for
characters.

/Peter


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
johnchx2@yahoo.com
Guest





PostPosted: Thu May 11, 2006 1:21 pm    Post subject: Re: Placement new and destructor Reply with quote



dragoncoder wrote:

Quote:
2. The second error is not a typographical error. I see at no place in
the code the destructor of the Foo object is called. Instead delete[]
buf calls the destructors of 16 char objects which is fine but I feel
there should be a call to Foo's destructor before the delete[] buf.
Shouldn't there be a call to pb->~Foo() before delete[] ?

Since Foo has a trivial destructor, omitting the destructor call does
no harm. If Foo's destructor were non-trivial and had side effects
upon which the behavior of the program depends, omitting the destructor
call would lead to undefined behavior (3.8.4).


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Eugene Alterman
Guest





PostPosted: Fri May 12, 2006 12:21 am    Post subject: Re: Placement new and destructor Reply with quote

"peter koch larsen" <peter.koch.larsen (AT) gmail (DOT) com> wrote in message
news:1147299859.239506.136800 (AT) i40g2000cwc (DOT) googlegroups.com...
Quote:
I have a feeling there might be a third error, however. The character
vector is allocated via new char[]. Is new char guaranteed to allocate
memory that is properly aligned for any datatype? So far as I
understand it, the buffer is only guaranteed to be properly aligned for
characters.

Storage for objects created using new-expression is allocated by an
allocation function (global operator new[] in this case) that is generally
the same regardless of the type of an object being created, and it is thus
aligned to satisfy the strictest alignment requirement. (3.7.3.1/2)


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Francis Glassborow
Guest





PostPosted: Fri May 12, 2006 4:21 am    Post subject: Re: Placement new and destructor Reply with quote

In article <1147272822.470577.270840 (AT) j33g2000cwa (DOT) googlegroups.com>,
dragoncoder <pktiwary (AT) gmail (DOT) com> writes
Quote:
Hello all,

I am reading C++ Primer 3rd edition by Lippman & Lajoie and come
across
the following piece of code as an example demostrating the use of
placement new.

A pity you did not choose to read the 4th edition. The third was good
but the complete rewrite that Barbara Moo did in producing the 4th
edition has turned a good book into an excellent one. Barbara is not
only a fluent writer but has a deep knowledge of both programming and
C++ (and has the good fortune to be married to another of the World's
great programmers and writers on programming -- Andy Koenig whose
influence can be seen between the words)


--
Francis Glassborow ACCU
Author of 'You Can Do It!'& 'You Can Program in C++'
see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/
youcandoit/projects


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
kanze
Guest





PostPosted: Sat May 13, 2006 1:21 am    Post subject: Re: Placement new and destructor Reply with quote

dan2online wrote:
Quote:
dragoncoder wrote:

2. The second error is not a typographical error. I see at
no place in the code the destructor of the Foo object is
called. Instead delete[] buf calls the destructors of 16
char objects which is fine but I feel there should be a call
to Foo's destructor before the delete[] buf. Shouldn't there
be a call to pb->~Foo() before delete[] ?

Foo *pb = new (buf) Foo means that Foo object reuses the
storage that ends the lifetime of buf. To delete 'buf' is to
destroy the object at the same time.

No it doesn't. delete[]buf will call the destructors of the
type pointed to by buf -- here, char.

Quote:
So don't need to delete pb here.

You're not allowed to delete pb, since pb wasn't allocated with
the standard allocator. It would be cleaner, however, if they
called pb->~Foo() before deleting buf.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
kanze
Guest





PostPosted: Sat May 13, 2006 1:21 am    Post subject: Re: Placement new and destructor Reply with quote

peter koch larsen wrote:

Quote:
I have a feeling there might be a third error, however. The
character vector is allocated via new char[]. Is new char
guaranteed to allocate memory that is properly aligned for any
datatype? So far as I understand it, the buffer is only
guaranteed to be properly aligned for characters.

There's a special exception when new'ing an array of character
types. The results of new char[] must be sufficiently aligned
for any type. (Never the less, I still prefer ::operator new(n)
and ::operator delete(p) when dealing with raw memory.)

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Eugene Alterman
Guest





PostPosted: Sat May 13, 2006 9:21 pm    Post subject: Re: Placement new and destructor Reply with quote

"Eugene Alterman" <eugalt (AT) verizon (DOT) net> wrote in message
news:hhJ8g.75476$H71.51854 (AT) newssvr13 (DOT) news.prodigy.com...
Quote:
"peter koch larsen" <peter.koch.larsen (AT) gmail (DOT) com> wrote in message
news:1147299859.239506.136800 (AT) i40g2000cwc (DOT) googlegroups.com...
I have a feeling there might be a third error, however. The character
vector is allocated via new char[]. Is new char guaranteed to allocate
memory that is properly aligned for any datatype? So far as I
understand it, the buffer is only guaranteed to be properly aligned for
characters.

Storage for objects created using new-expression is allocated by an
allocation function (global operator new[] in this case) that is generally
the same regardless of the type of an object being created, and it is thus
aligned to satisfy the strictest alignment requirement. (3.7.3.1/2)

And this is not sufficient because there may be more space allocated with
the array at some offset from the beginning of the allocated storage.
But there is a special rule for char arrays that require them to be
sufficiently aligned for any object that could be placed into such an array.
(5.3.4/10)


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Tomás
Guest





PostPosted: Sat May 13, 2006 9:21 pm    Post subject: Re: Placement new and destructor Reply with quote

kanze posted:

Quote:
There's a special exception when new'ing an array of character
types. The results of new char[] must be sufficiently aligned
for any type. (Never the less, I still prefer ::operator new(n)
and ::operator delete(p) when dealing with raw memory.)

If I'm dealing with raw memory, or allocating memory for an array of POD's
for example, I like to use malloc -- I feel that it's more honest, so to
speak.

Malloc is always my first choice... it's only if I'm dealing with a fancy
class type (or writing a template) that I resort to "new" and "delete".

-Tomás

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Eugene Alterman
Guest





PostPosted: Sat May 13, 2006 9:21 pm    Post subject: Re: Placement new and destructor Reply with quote

"kanze" <kanze@gabi-soft.fr> wrote in message
news:1147437953.261536.79720 (AT) d71g2000cwd (DOT) googlegroups.com...
Quote:
peter koch larsen wrote:

I have a feeling there might be a third error, however. The
character vector is allocated via new char[]. Is new char
guaranteed to allocate memory that is properly aligned for any
datatype? So far as I understand it, the buffer is only
guaranteed to be properly aligned for characters.

There's a special exception when new'ing an array of character
types. The results of new char[] must be sufficiently aligned
for any type.

That could fit into that array, that is.
There would be no alignment requirements for new char[1], for example.

(Never the less, I still prefer ::operator new(n)
Quote:
and ::operator delete(p) when dealing with raw memory.)

That would make sense if new char[] has memory overhead.
I wonder what could be the purpose of such an overhead?


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Francis Glassborow
Guest





PostPosted: Sun May 14, 2006 12:21 pm    Post subject: Re: Placement new and destructor Reply with quote

In article <dXk9g.9116$j7.305540 (AT) news (DOT) indigo.ie>, Tomás <NULL (AT) NULL (DOT) NULL>
writes
Quote:
kanze posted:

There's a special exception when new'ing an array of character
types. The results of new char[] must be sufficiently aligned
for any type. (Never the less, I still prefer ::operator new(n)
and ::operator delete(p) when dealing with raw memory.)

If I'm dealing with raw memory, or allocating memory for an array of POD's
for example, I like to use malloc -- I feel that it's more honest, so to
speak.

Malloc is always my first choice... it's only if I'm dealing with a fancy
class type (or writing a template) that I resort to "new" and "delete".

Then I think you are mistaken because operator new was designed to
provide raw memory in C++. In many implementations the global version
may just be a call to malloc() but it does not have to be. It is not a
matter of honesty but a matter of making use of the language. If you use
operator new you can benefit from replacement versions designed for such
things as tracking memory leaks.


--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Tomás
Guest





PostPosted: Sun May 14, 2006 9:21 pm    Post subject: Re: Placement new and destructor Reply with quote

Francis Glassborow posted:

Quote:
Then I think you are mistaken because operator new was designed to
provide raw memory in C++. In many implementations the global version
may just be a call to malloc() but it does not have to be. It is not a
matter of honesty but a matter of making use of the language. If you
use operator new you can benefit from replacement versions designed for
such things as tracking memory leaks.

I regularly play with references to get exactly what I want. For example,
if I wanted an array of five thousand int's, I wouldn't write:

int * const p = std::malloc( 5000 * sizeof(*p) );

I'd write:

unsigned long const len = 5000;

int (&array)[len] =
*static_cast<int (*)[len]>(
std::malloc( len * sizeof(*p) )
);

Then when I want to delete the memory, I can simply write:

free(array);

because I know that array will implicitly convert to "int*", which will
implicitly convert to "void*" (which is what "free" takes as an argument).

However, it gets messy if I want to use "delete", because then I have to
make sure that I get the types EXACTLY right. Plus, I don't know how legal
the following line is:

int (&array)[len] = *static_cast<int (*)[len]>(new int[len]);

I could use the following in its place:

int (&array)[len] = *new int[len][0];

But then I would have to worry about passing a multi-dimensional pointer
type to "delete"...
(Actually it just occurred to me know that I could probably write the
following:)

int (&array)[len] = *new int[len][0];

delete &array;


I'll have to check if that's okay...

-Tomás

-Tomás

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
kanze
Guest





PostPosted: Mon May 15, 2006 1:21 pm    Post subject: Re: Placement new and destructor Reply with quote

Eugene Alterman wrote:
Quote:
"kanze" <kanze@gabi-soft.fr> wrote in message
news:1147437953.261536.79720 (AT) d71g2000cwd (DOT) googlegroups.com...
peter koch larsen wrote:

I have a feeling there might be a third error, however.
The character vector is allocated via new char[]. Is new
char guaranteed to allocate memory that is properly aligned
for any datatype? So far as I understand it, the buffer is
only guaranteed to be properly aligned for characters.

There's a special exception when new'ing an array of
character types. The results of new char[] must be
sufficiently aligned for any type.

That could fit into that array, that is. There would be no
alignment requirements for new char[1], for example.

I think that the alignment requirement still stands (but the
issue isn't important enough for me to bother looking it up).

Quote:
(Never the less, I still prefer ::operator new(n)
and ::operator delete(p) when dealing with raw memory.)

That would make sense if new char[] has memory overhead. I
wonder what could be the purpose of such an overhead?

Coherence with array new of types with a destructor?

But that's not my motive. My motive is communicating with the
reader: new X[n] means allocating and "constructing" n new
objects of type X. The fact that the constructor is a no-op is
in my mind irrelevant -- new char[n] tells the reader I'm
allocating char's. The operator new() function tells the reader
I'm allocating raw memory, which I will "construct" later.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
James Kanze
Guest





PostPosted: Tue May 23, 2006 11:21 am    Post subject: Re: Placement new and destructor Reply with quote

Eugene Alterman wrote:
Quote:
"kanze" <kanze@gabi-soft.fr> wrote in message
news:1147684409.380016.226040 (AT) v46g2000cwv (DOT) googlegroups.com...
Eugene Alterman wrote:
"kanze" <kanze@gabi-soft.fr> wrote in message
news:1147437953.261536.79720 (AT) d71g2000cwd (DOT) googlegroups.com...
There's a special exception when new'ing an array of
character types. The results of new char[] must be
sufficiently aligned for any type.
That could fit into that array, that is. There would be no
alignment requirements for new char[1], for example.
I think that the alignment requirement still stands (but the
issue isn't important enough for me to bother looking it up).

I did. :-)

5.3.4/10
quote
For arrays of char and unsigned char, the difference between
the result of the new-expression and the address returned by
the allocation function shall be an integral multiple of the
most stringent alignment requirement (3.9) of any object type
whose size is no greater than the size of the array being
created.
/quote

Does it mean that the above does not apply to signed char, BTW?

That's what it says. If it were meant to apply to signed
char as well, they would have written "For arrays of character
type". (Or would that require it to apply to wchar_t as well?)

Generally, I think that there is an intent in C++ (or parts of
it), that char can be used for raw memory, as well as unsigned
char. This is a change with respect to C (where char can
explicitly have trapping values, so looking at an object as an
array of char may not work).

--
James Kanze kanze.james (AT) neuf (DOT) fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Eugene Alterman
Guest





PostPosted: Wed May 24, 2006 4:21 pm    Post subject: Re: Placement new and destructor Reply with quote

"James Kanze" <kanze.james (AT) neuf (DOT) fr> wrote in message
news:e4mnhr$pq2$1 (AT) emma (DOT) aioe.org...
Quote:
Generally, I think that there is an intent in C++ (or parts of
it), that char can be used for raw memory, as well as unsigned
char. This is a change with respect to C (where char can
explicitly have trapping values,

What is that?

Quote:
so looking at an object as an
array of char may not work).


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.