 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
James Hopkin Guest
|
Posted: Tue Nov 09, 2004 9:20 pm Post subject: Placement new return value |
|
|
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
|
Posted: Wed Nov 10, 2004 4:26 pm Post subject: Re: Placement new return value |
|
|
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
|
Posted: Wed Nov 10, 2004 4:26 pm Post subject: Re: Placement new return value |
|
|
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
|
Posted: Wed Nov 10, 2004 4:28 pm Post subject: Re: Placement new return value |
|
|
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
|
Posted: Thu Nov 11, 2004 11:13 am Post subject: Re: Placement new return value |
|
|
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
|
Posted: Thu Nov 11, 2004 11:15 am Post subject: Re: Placement new return value |
|
|
[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
|
Posted: Fri Nov 12, 2004 4:05 am Post subject: Re: Placement new return value |
|
|
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
|
Posted: Fri Nov 12, 2004 12:10 pm Post subject: Re: Placement new return value |
|
|
"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
|
Posted: Fri Nov 12, 2004 3:08 pm Post subject: Re: Placement new return value |
|
|
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
|
Posted: Sun Nov 14, 2004 8:40 pm Post subject: Re: Placement new return value |
|
|
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
|
Posted: Wed Nov 17, 2004 2:13 am Post subject: Re: Placement new return value |
|
|
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?
|
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
|
Posted: Thu Nov 18, 2004 12:42 am Post subject: Re: Placement new return value |
|
|
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
|
Posted: Fri Nov 19, 2004 12:57 pm Post subject: Re: Placement new return value |
|
|
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
|
Posted: Fri Nov 19, 2004 4:06 pm Post subject: Re: Placement new return value |
|
|
"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
|
Posted: Sat Nov 20, 2004 6:14 pm Post subject: Re: Placement new return value |
|
|
"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 |
|
 |
|
|
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
|
|