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 return value
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
James Hopkin
Guest





PostPosted: Tue Nov 09, 2004 9:20 pm    Post subject: Placement new return value Reply with quote



Dear all

Given any type T and a pointer, p, to suitably aligned memory, if I do

#include <new>
new (p) T;

is

static_cast<T*>(p)

subsequently guaranteed to be a valid pointer to the newed object? I
believe it is, but I'm not sure where to look in the standard for
confirmation.


Thanks in advance

James

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





PostPosted: Wed Nov 10, 2004 4:26 pm    Post subject: Re: Placement new return value Reply with quote



James Hopkin wrote:
Quote:
Dear all

Given any type T and a pointer, p, to suitably aligned memory, if I do

#include <new
new (p) T;

is

static_cast
subsequently guaranteed to be a valid pointer to the newed object? I
believe it is, but I'm not sure where to look in the standard for
confirmation.

To be precise, it's static_cast<T*>(static_cast<void*>(p)) that is
guaranteed to be a valid pointer. The cast to void* is required in case
p is a pointer to a type multiply or virtually derived from T.

The guarantee comes from §4.10/2 and the fact that that placement form
of operator new returns its argument (§18.4.1.3/2).

Alberto

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

Back to top
Victor Bazarov
Guest





PostPosted: Wed Nov 10, 2004 4:26 pm    Post subject: Re: Placement new return value Reply with quote



James Hopkin wrote:
Quote:
Given any type T and a pointer, p, to suitably aligned memory, if I do

#include <new
new (p) T;

is

static_cast
subsequently guaranteed to be a valid pointer to the newed object? I
believe it is, but I'm not sure where to look in the standard for
confirmation.

18.4.1.3

V

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

Back to top
Ron Natalie
Guest





PostPosted: Wed Nov 10, 2004 4:28 pm    Post subject: Re: Placement new return value Reply with quote

James Hopkin wrote:
Quote:
Dear all

Given any type T and a pointer, p, to suitably aligned memory, if I do

#include <new
new (p) T;

is

static_cast
subsequently guaranteed to be a valid pointer to the newed object? I
believe it is, but I'm not sure where to look in the standard for
confirmation.

Yes, but that is not the case for

new (p) T[n];

The standard doesn't come right out and say it, but the allocator for
a scalar new gets the exact size of the requested type. The array
new is the array length times the size plus some overhead.

See 5.3.4/10 and 12

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

Back to top
Maxim Yegorushkin
Guest





PostPosted: Thu Nov 11, 2004 11:13 am    Post subject: Re: Placement new return value Reply with quote

On 9 Nov 2004 16:20:15 -0500, James Hopkin
<jhopkin (AT) reflectionsinteractive (DOT) com> wrote:

Quote:
Given any type T and a pointer, p, to suitably aligned memory, if I do

#include <new
new (p) T;

is

static_cast
subsequently guaranteed to be a valid pointer to the newed object? I
believe it is, but I'm not sure where to look in the standard for
confirmation.

Only when p has type of void*. Standard guaranties that pointer of any
type can be safely converted only to void* and back.

--
Maxim Yegorushkin

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

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Thu Nov 11, 2004 11:15 am    Post subject: Re: Placement new return value Reply with quote

[email]jhopkin (AT) reflectionsinteractive (DOT) com[/email] (James Hopkin) wrote in message
news:<a0368c9c.0411090317.2517b5f7 (AT) posting (DOT) google.com>...

Quote:
Given any type T and a pointer, p, to suitably aligned memory, if I do

#include <new
new (p) T;

is

static_cast
subsequently guaranteed to be a valid pointer to the newed object?

Not if T is an array type. Otherwise, I think so, but I'm not too sure
where to look either.

--
James Kanze GABI Software http://www.gabi-soft.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
Maxim Yegorushkin
Guest





PostPosted: Fri Nov 12, 2004 4:05 am    Post subject: Re: Placement new return value Reply with quote

On 10 Nov 2004 11:28:48 -0500, Ron Natalie <ron (AT) sensor (DOT) com> wrote:

Quote:
James Hopkin wrote:
Dear all

Given any type T and a pointer, p, to suitably aligned memory, if I
do

#include <new
new (p) T;

is

static_cast
subsequently guaranteed to be a valid pointer to the newed object? I
believe it is, but I'm not sure where to look in the standard for
confirmation.

Yes, but that is not the case for
new (p) T[n];

How about this:

struct T { int n; };
struct U { int m; };
struct V : U, T {};

V v, *p = &v;
new (p) T;
static_cast<T*>(p); // oops, points to (char*)p + sizeof(int) --
to
(uninitialized) T subobject of nonexistent V

--
Maxim Yegorushkin

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

Back to top
Thomas Mang
Guest





PostPosted: Fri Nov 12, 2004 12:10 pm    Post subject: Re: Placement new return value Reply with quote


"Maxim Yegorushkin" <e-maxim (AT) yandex (DOT) ru> schrieb im Newsbeitrag
news:opsg8rv5rrti5cme (AT) devlx007 (DOT) ipcb.net...
Quote:
On 9 Nov 2004 16:20:15 -0500, James Hopkin
[email]jhopkin (AT) reflectionsinteractive (DOT) com[/email]> wrote:

Given any type T and a pointer, p, to suitably aligned memory, if I do

#include <new
new (p) T;

is

static_cast
subsequently guaranteed to be a valid pointer to the newed object? I
believe it is, but I'm not sure where to look in the standard for
confirmation.

Only when p has type of void*. Standard guaranties that pointer of any
type can be safely converted only to void* and back.


If I read the Standard correctly, the conversions from base <-> derived are
also guaranteed to work.



Now take this example:


class some_class{};

int main()
{
void* Memory = new char[10 * sizeof(some_class)];
some_class * Buffer = static_cast<some_class*>(Memory);
}


The array-new expression yields a void * (a), that is then converted to a
char* (b) and then back to void* (c).
Now this void* is converted into some_class* (d).


a -> c should be fine, what about d?
From one point of view, we are only converting a void * to a some_class*
(c -> d). However, this is a subsequence of the conversion from a char* to a
some_class* (b -> d).


Is this little programm now defined or not?




Another question regarding the same idiom of allocating a buffer in a
char[]:

Is this line:

some_class * Buffer = (some_class*) new char[10 * sizeof(some_class)];

equivalent to 1)

some_class * Buffer = static_cast<some_class*>(static_cast<void*>(new
char[10 * sizeof(some_class)]));

or equivalent to 2)

some_class * Buffer = reinterpret_cast<some_class*>(new char[10 *
sizeof(some_class)]);

????

In case 1), the same issue as raised above would apply.

In case 2), the result is unspecified anyways.



Thomas








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

Back to top
Branimir Maksimovic
Guest





PostPosted: Fri Nov 12, 2004 3:08 pm    Post subject: Re: Placement new return value Reply with quote

Ron Natalie <ron (AT) sensor (DOT) com> wrote

Quote:
James Hopkin wrote:
Dear all

Given any type T and a pointer, p, to suitably aligned memory, if I do

#include <new
new (p) T;

is

static_cast
subsequently guaranteed to be a valid pointer to the newed object? I
believe it is, but I'm not sure where to look in the standard for
confirmation.

Yes, but that is not the case for
new (p) T[n];

The standard doesn't come right out and say it, but the allocator for
a scalar new gets the exact size of the requested type. The array
new is the array length times the size plus some overhead.

See 5.3.4/10 and 12

This rises another question.
When using
void* operator new[](size_t s)throw(std::bad_alloc);
compiler does the trick of calculating *that* overhead;
but, in case of placement version there is no portable way of knowing
how much bytes to reserve for it.
So we must supply another version of placement new in order
to avoid buffer overuns:
void* operator new[](size_t required_size,size_t real_size,void* p)
throw(std::bad_alloc)
{
if(real_size return p;
}


This is the question:
Is placement version of array new completely useless? :)

Greetings, Bane.

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

Back to top
Maxim Yegorushkin
Guest





PostPosted: Sun Nov 14, 2004 8:40 pm    Post subject: Re: Placement new return value Reply with quote

Thomas Mang wrote:

Quote:
Only when p has type of void*. Standard guaranties that pointer of any
type can be safely converted only to void* and back.


If I read the Standard correctly, the conversions from base <-> derived
are also guaranteed to work.

Yes, but in the case with multiple base classes a compiler may adjust a
pointer, so that the cast result is not equal to the casted pointer.
Please, see my previous posting for a sample.

--
Maxim Yegorushkin

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

Back to top
Thomas Richter
Guest





PostPosted: Wed Nov 17, 2004 2:13 am    Post subject: Re: Placement new return value Reply with quote

Hi,

Quote:
When using
void* operator new[](size_t s)throw(std::bad_alloc);
compiler does the trick of calculating *that* overhead;
but, in case of placement version there is no portable way of knowing
how much bytes to reserve for it.

Right, but you don't need to. The compiler computes that, and includes it
in the size argument. Which is in bytes.

Quote:
So we must supply another version of placement new in order
to avoid buffer overuns:
void* operator new[](size_t required_size,size_t real_size,void* p)
throw(std::bad_alloc)
{
if(real_size return p;
}

No. What for? The operator new[] only provides raw memory. You ain't
supposed to know how many elements you need to reserve memory for.
Only the size of the memory is required to get it.

Quote:
This is the question:
Is placement version of array new completely useless? Smile

No.

So long,
Thomas




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

Back to top
Branimir Maksimovic
Guest





PostPosted: Thu Nov 18, 2004 12:42 am    Post subject: Re: Placement new return value Reply with quote

Thomas Richter <thor (AT) cleopatra (DOT) math.tu-berlin.de> wrote

Quote:
Hi,

When using
void* operator new[](size_t s)throw(std::bad_alloc);
compiler does the trick of calculating *that* overhead;
but, in case of placement version there is no portable way of knowing
how much bytes to reserve for it.

Right, but you don't need to. The compiler computes that, and includes it
in the size argument. Which is in bytes.

Of course, but I'm simply asking this:

class A{
public:
A(): puff_(0xdeadbeef)
{
}
int puff()const{ return puff_; }
~A(){std::cout< private:
int puff_;
};

int main()
{

// Question: will this segfault on some systems?
char buf[10*sizeof(A)];
A* abuf = new ((void*)buf) A[10];
for(size_t i = 0;i<10;++i)
{
std::cout< abuf[i].~A();
}

}


Quote:

So we must supply another version of placement new in order
to avoid buffer overuns:
void* operator new[](size_t required_size,size_t real_size,void* p)
throw(std::bad_alloc)
{
if(real_size return p;
}

No. What for? The operator new[] only provides raw memory. You ain't
supposed to know how many elements you need to reserve memory for.
Only the size of the memory is required to get it.


Number of elements is not a question.
I mean this:
char buf[num_of_el*sizeof(T)];

new (sizeof(buf), (void*)buf) T[num_of_el];
// supplied version can throw std::bad_alloc

Greetings, Bane.

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

Back to top
Thomas Richter
Guest





PostPosted: Fri Nov 19, 2004 12:57 pm    Post subject: Re: Placement new return value Reply with quote

Hi,

Quote:
Right, but you don't need to. The compiler computes that, and includes it
in the size argument. Which is in bytes.

Of course, but I'm simply asking this:

/* snip */

Quote:
// Question: will this segfault on some systems?
char buf[10*sizeof(A)];
A* abuf = new ((void*)buf) A[10];
for(size_t i = 0;i<10;++i)
{
std::cout< abuf[i].~A();
}

Ok, I see what you're aiming at. The point is that you cannot know the
byte size of the required memory in advance, thus you cannot use placement
array new for a placement allocation. (-; Thus, the above could really
segfault. But that doesn't render placement array new useless. It just
has other uses.

I guess the main problem is its name. Placement new can do a lot of
wonderful things besides "placing" objects into memory. It should rather
be called "new with parameters". A typical use for the placement new argument
would be that of a memory pool handle from which the memory has to be taken
for the allocation. In the above example, you wouldn't need to use placement
new in first place. Just allocating the "A" class objects one after another
at (buf + i * sizeof(A)) would also do that without the problem at hand
(keeping care of proper exception handling as well).

So long,
Thomas


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

Back to top
Thomas Mang
Guest





PostPosted: Fri Nov 19, 2004 4:06 pm    Post subject: Re: Placement new return value Reply with quote


"Branimir Maksimovic" <bmaxa (AT) volomp (DOT) com> schrieb im Newsbeitrag
news:88cdcbb3.0411171007.543e21e2 (AT) posting (DOT) google.com...
Quote:
Thomas Richter <thor (AT) cleopatra (DOT) math.tu-berlin.de> wrote

Hi,

When using
void* operator new[](size_t s)throw(std::bad_alloc);
compiler does the trick of calculating *that* overhead;
but, in case of placement version there is no portable way of knowing
how much bytes to reserve for it.

Right, but you don't need to. The compiler computes that, and includes
it
in the size argument. Which is in bytes.

Of course, but I'm simply asking this:

class A{
public:
A(): puff_(0xdeadbeef)
{
}
int puff()const{ return puff_; }
~A(){std::cout< private:
int puff_;
};

int main()
{

// Question: will this segfault on some systems?
char buf[10*sizeof(A)];
A* abuf = new ((void*)buf) A[10];
for(size_t i = 0;i<10;++i)
{
std::cout< abuf[i].~A();
}

Of course it can because it is undefined behaviour.

First, you assign a value to an int the Standard does not guarantee it can
represent.
Second, you ignore alignment.


Thomas



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

Back to top
Branimir Maksimovic
Guest





PostPosted: Sat Nov 20, 2004 6:14 pm    Post subject: Re: Placement new return value Reply with quote

"Thomas Mang" <nospam (AT) nospam (DOT) invalid> wrote

Quote:
"Branimir Maksimovic" <bmaxa (AT) volomp (DOT) com> schrieb im Newsbeitrag
news:88cdcbb3.0411171007.543e21e2 (AT) posting (DOT) google.com...
Thomas Richter <thor (AT) cleopatra (DOT) math.tu-berlin.de> wrote in message
news:<cnct35$ne1$1 (AT) mamenchi (DOT) zrz.TU-Berlin.DE>...
Hi,

When using
void* operator new[](size_t s)throw(std::bad_alloc);
compiler does the trick of calculating *that* overhead;
but, in case of placement version there is no portable way of knowing
how much bytes to reserve for it.

Right, but you don't need to. The compiler computes that, and includes
it
in the size argument. Which is in bytes.

Of course, but I'm simply asking this:

class A{
public:
A(): puff_(0xdeadbeef)
{
}
int puff()const{ return puff_; }
~A(){std::cout< private:
int puff_;
};

int main()
{

// Question: will this segfault on some systems?
char buf[10*sizeof(A)];
A* abuf = new ((void*)buf) A[10];
for(size_t i = 0;i<10;++i)
{
std::cout< abuf[i].~A();
}

Of course it can because it is undefined behaviour.

First, you assign a value to an int the Standard does not guarantee it can
represent.
Second, you ignore alignment.

You got it wrong. It is not undefined behavior because of that.
First check out 4.7, it says value is implementation defined if
it cannot be represented in destination signed type.
Alse see 5.3.4/10 for explanation why alignment is not an issue here.
The other Thomas got it right. Problem is that you cannot portably know
*right* size without digging out parameter from operator new[].

Greetings, Bane.

[ 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.