关于使用“安置”的问题新 [英] Question on use of "placement" new

查看:62
本文介绍了关于使用“安置”的问题新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




我们有一个类,其对象将在共享内存中分配。为了
,定义了一个ShmManager基类,以便重新定义operator new和

delete以在共享内存中分配段。典型的

类Foo然后从ShmManager继承以获得此行为。

类ShmManager {


void * operator new(size_t size);

void operator delete(void * p,size_t size);


};


class Foo:public ShmManager

{


int fData1;

Barr fData2 [16];


};


在前面的Foo示例中,fData2数组的大小在

编译时已知,但我们需要将此大小设置为动态,但保持

对象内存布局平坦。


我们正在使用展示位置新语法:


类Foo1:public ShmManager

{


int fData1;

Barr fData2 []; //将使用展示位置进行扩展新的


};


ShmManager * ptr = ShmManager :: operator new(sizeof(Foo1)+ num *

sizeof(Barr));

Foo1 * = new(ptr)Foo1();


这样Foo1对象就会得到一个动态的num ;元素数量。这个

似乎有效,但这样做安全吗?我们是否有义务将

fData2作为Foo1中的* last *元素?是否有更好的/

更安全的方式来实现相同的模式?


谢谢

$ b $bStéphaneLetz

Hi,

We have a class whose objects are to be allocated in shared memory. To
do that a ShmManager base class is defined so that operator new and
delete are redefined to allocate segments in shared memory. A typical
class "Foo" then inherit from ShmManager to have get this behaviour.
class ShmManager {

void* operator new(size_t size);
void operator delete(void* p, size_t size);

};

class Foo : public ShmManager
{

int fData1;
Barr fData2[16];

};

In the previous Foo example, the size of fData2 array is known at
compilation time, but we need to make this size "dynamic", but keeping
the object memory layout "flat".

We are using the "placement" new syntax doing:

class Foo1 : public ShmManager
{

int fData1;
Barr fData2[]; // will be extented using "placement" new

};

ShmManager* ptr = ShmManager::operator new(sizeof(Foo1) + num *
sizeof(Barr));
Foo1* = new(ptr) Foo1();

So that Foo1 object nows gets a dynamic "num" number of elements. This
seems to work, but is this safe to do that? Are we obliged to put the
fData2 fied as the *last* element in the Foo1? Is there any better/
safer manner to implement the same pattern?

Thanks

Stéphane Letz

推荐答案

le**@grame.fr 在新闻中写道: dd732c4c-3cd7-4319-ae60-be2cb2a487a6

@ d77g2000hsb.googlegroups.com:
le**@grame.fr wrote in news:dd732c4c-3cd7-4319-ae60-be2cb2a487a6
@d77g2000hsb.googlegroups.com:




我们有一个类,其对象将在共享内存中分配。为了
,定义了一个ShmManager基类,以便重新定义operator new和

delete以在共享内存中分配段。典型的

类Foo然后从ShmManager继承以获得此行为。


类ShmManager {


void * operator new(size_t size);

void operator delete(void * p,size_t size);


};


class Foo:public ShmManager

{


int fData1;

Barr fData2 [16];


};


在前面的Foo示例中,fData2数组的大小在

编译时已知,但我们需要将此大小设置为动态,但保持

对象内存布局平坦。
Hi,

We have a class whose objects are to be allocated in shared memory. To
do that a ShmManager base class is defined so that operator new and
delete are redefined to allocate segments in shared memory. A typical
class "Foo" then inherit from ShmManager to have get this behaviour.
class ShmManager {

void* operator new(size_t size);
void operator delete(void* p, size_t size);

};

class Foo : public ShmManager
{

int fData1;
Barr fData2[16];

};

In the previous Foo example, the size of fData2 array is known at
compilation time, but we need to make this size "dynamic", but keeping
the object memory layout "flat".



我想这就是你要说的,例如std :: vector是非法的。

I guess with this you meant to say that e.g. std::vector is outlawed.


>

我们正在使用placement新语法:


类Foo1:public ShmManager

{


int fData1;

Barr fData2 []; //将使用展示位置进行扩展新
>
We are using the "placement" new syntax doing:

class Foo1 : public ShmManager
{

int fData1;
Barr fData2[]; // will be extented using "placement" new



这不是有效的C ++。这是C中的有效语法和一些C ++编译器

可能接受此作为扩展。 AFAIK没有计划在C ++ 0x中包含这个功能,因为在C ++中有更好的方法可以动态地调整大小数组(std :: vector,... )。因此在C ++中你有义务将它作为Barr fData2 [1]声明为
;但是,访问0以外的元素是

未定义的行为(可能恰好由您的特定

实现定义)。在实践中,我怀疑你的代码适用于大多数主流实现,但标准并不能保证这一点。

This is not valid C++. This is valid syntax in C and some C++ compilers
might accept this as an extension. AFAIK it is not planned to include
this feature in C++0x as in C++ there are better means for dynamically
sized arrays (std::vector, ...). Thus in C++ you are obliged to declare
it as Barr fData2[1]; however, accessing elements other than 0 is
undefined behavior (which might happen to be defined by your particular
implementation). In practice I suspect that your code works on most
mainstream implementations, but this is not guaranteed by the standard.


};


ShmManager * ptr = ShmManager :: operator new(sizeof(Foo1)+ num *

sizeof(Barr));

Foo1 * = new(ptr)Foo1();
};

ShmManager* ptr = ShmManager::operator new(sizeof(Foo1) + num *
sizeof(Barr));
Foo1* = new(ptr) Foo1();



Foo1 * p_foo1 = new(ptr)Foo1();

Foo1* p_foo1 = new(ptr) Foo1();


>

这样Foo1对象就会得到一个动态的num数字。元素数量。这个

似乎有效,但这样做安全吗?我们是否有义务将

fData2作为Foo1中的* last *元素?
>
So that Foo1 object nows gets a dynamic "num" number of elements. This
seems to work, but is this safe to do that? Are we obliged to put the
fData2 fied as the *last* element in the Foo1?



当然。最好不要从那个类派生。

Sure. And better not derive from that class.


有没有更好的/

更安全的方式来实现相同的模式?
Is there any better/
safer manner to implement the same pattern?



使用C?


一个选项是让fData2退出类定义,

像现在一样分配内存,并获得Barr数组指针

类似于:


Barr * barr = static_cast< Barr *> (static_cast< void *>(p_foo1 + 1));


如果Barr的对齐要求与Foo1相同或更低

严格,我认为这应该是犹太人,我相信其他人如果我错了,他们会纠正我。


hth

Paavo

Using C?

One option would be to let the fData2 out of the class definition,
allocate memory as you do now, and obtain the Barr array pointer by
something like:

Barr* barr = static_cast<Barr*>( static_cast<void*>(p_foo1+1));

Provided that the alignment requirements for Barr are the same or less
stringent than for Foo1, I think this should be kosher, I''m sure others
will correct me if I''m wrong.

hth
Paavo


On 17 Maj,18:15,l ... @ grame.fr写道:
On 17 Maj, 18:15, l...@grame.fr wrote:




我们有一个类,其对象将在共享内存中分配。为了
,定义了一个ShmManager基类,以便重新定义operator new和

delete以在共享内存中分配段。典型的

类Foo然后继承自ShmManager以获得此行为。


类ShmManager {


* * * * void * operator new(size_t size);

* * * * void operator delete(void * p,size_t size);


};


class Foo:public ShmManager

{


* * * * * int fData1;

* * * * * Barr fData2 [ 16];


};


在前面的Foo示例中,fData2数组的大小为

编译时间,但我们需要使这个大小动态,但保持对象存储器布局平坦。
Hi,

We have a class whose objects are to be allocated in shared memory. To
do that a ShmManager base class is defined so that operator new and
delete are redefined to allocate segments in shared memory. A typical
class "Foo" then inherit from ShmManager to have get this behaviour.

class ShmManager {

* * * * void* operator new(size_t size);
* * * * void operator delete(void* p, size_t size);

};

class Foo : public ShmManager
{

* * * * * int fData1;
* * * * * Barr fData2[16];

};

In the previous Foo example, the size of fData2 array is known at
compilation time, but we need to make this size "dynamic", but keeping
the object memory layout "flat".



为什么必须保持平稳?你不能在C ++中做到这一点,并且这里存在

潜在的问题 - 例如如果Barrs对齐不兼容

与int的对比。

我将假设一个解决方案,其中fData2是指向内存的指针

相邻到fData1。

Why must it be flat? You can''t do that portably in C++ and there are
potential problems here - e.g. if Barrs alignment is not compatible
with that of int.
I will assume that a solution where fData2 is a pointer to memory not
adjacent to fData1.


>

我们使用的是展示位置新语法在做:


类Foo1:public ShmManager

{


* * * * * int fData1;

* * * * * Barr fData2 []; * //将使用展示位置进行扩展新的


};


ShmManager * ptr = ShmManager :: operator new(sizeof(Foo1)+ num *

sizeof(Barr));

Foo1 * = new(ptr)Foo1();
>
We are using the "placement" new syntax doing:

class Foo1 : public ShmManager
{

* * * * * int fData1;
* * * * * Barr fData2[]; *// will be extented using "placement" new

};

ShmManager* ptr = ShmManager::operator new(sizeof(Foo1) + num *
sizeof(Barr));
Foo1* = new(ptr) Foo1();



这里没有理由从ShmManager继承。只有在你可以直接使用新的Foo1

的情况下才需要


There is no reason to inherit from ShmManager here. This would have
been necessary only in the case where you would be able to new Foo1
directly.


>

这样Foo1对象就会得到一个动态的num数字。元素数量。这个

似乎有效,但这样做安全吗?我们是否有义务将

fData2作为Foo1中的* last *元素?是否有更好的/

更安全的方式来实现相同的模式?
>
So that Foo1 object nows gets a dynamic "num" number of elements. This
seems to work, but is this safe to do that? Are we obliged to put the
fData2 fied as the *last* element in the Foo1? Is there any better/
safer manner to implement the same pattern?



有问题:

*您的代码将有16次调用Barr构造函数,这是

当num为16时才正确。要解决这个问题,你需要扩展

你的代码。

*前面提到的对齐问题。

*不便携。上面的代码不是有效的C ++,你可能会为此遇到麻烦。


如果要求只有fData2元素必须是

有条不紊,存在更好的解决方案。你的解决方案是不便携的

而且很脆弱,但有时候你可能不得不忍受这个。


/ Peter

There are problems:
* your code will have 16 calls to the Barr constructor and this is
only correct when num is 16. To solve this problem, you need to extend
your code.
* The alignment problems mentioned before.
* The nonportability. The code above is not valid C++, and you might
get into troubles for that.

If the requirement was that only the fData2 elements would have to be
contigious, much better solutions exist. Your solution is nonportable
and fragile, but sometimes you just might have to live with that.

/Peter


On 17 mai,19:49,peter koch< peter.koch.lar ... @ gmail.comwrote:
On 17 mai, 19:49, peter koch <peter.koch.lar...@gmail.comwrote:

On 17 Maj, 18:15,l ... @ grame.fr写道:
On 17 Maj, 18:15, l...@grame.fr wrote:


Hi,


我们有一个类,其对象将在共享内存中分配。为了
,定义了一个ShmManager基类,以便重新定义operator new和

delete以在共享内存中分配段。典型的

类Foo然后从ShmManager继承以获得此行为。
We have a class whose objects are to be allocated in shared memory. To
do that a ShmManager base class is defined so that operator new and
delete are redefined to allocate segments in shared memory. A typical
class "Foo" then inherit from ShmManager to have get this behaviour.


class ShmManager {
class ShmManager {


* * * * void * operator new(size_t size);

* * * * void operator delete(void * p,size_t size);
* * * * void* operator new(size_t size);
* * * * void operator delete(void* p, size_t size);


};
};


class Foo:public ShmManager

{
class Foo : public ShmManager
{


* * * * * int fData1;

* * * * * Barr fData2 [16];
* * * * * int fData1;
* * * * * Barr fData2[16];


};
};


在前面的Foo示例中,fData2数组的大小在

编译时已知,但我们需要制作这个大小动态,但保持对象存储器布局平坦。
In the previous Foo example, the size of fData2 array is known at
compilation time, but we need to make this size "dynamic", but keeping
the object memory layout "flat".



为什么必须保持平稳?


Why must it be flat?



Remerber对象存在于共享内存中,然后让它平坦。非常好

简化它的使用:任何需要它的进程都会获得基础对象

指针并且可以直接访问任何字段。

你不能在C ++中做到这一点并且在这里有

Remerber the object lives in shared mem, then having it "flat" greatly
simplify it''s use: any process that needs it gets the base object
pointer and can access any field "directly".
You can''t do that portably in C++ and there are


潜在的问题 - 例如如果Barrs对齐不兼容

与int的对比。

我将假设一个解决方案,其中fData2是指向内存的指针

相邻到fData1。
potential problems here - e.g. if Barrs alignment is not compatible
with that of int.
I will assume that a solution where fData2 is a pointer to memory not
adjacent to fData1.



如果我们切换到fData2 a在别处分配的解决方案,(在我们的例子中,
在另一个共享内存段中)那么我们必须用更复杂的内存访问方案来处理

,这也是因为共享的内存问题。

If we switch to a solution where fData2 a allocated elsewhere, (that
is in another shared memory segment in our case) then we have to deal
with more complex memory access scheme, again because of the shared
memory issue.


>


如果要求只有fData2元素必须是
有条不紊,存在更好的解决方案。你的解决方案是不便携的

而且很脆弱,但有时候你可能不得不忍受。
>

If the requirement was that only the fData2 elements would have to be
contigious, much better solutions exist. Your solution is nonportable
and fragile, but sometimes you just might have to live with that.



最初的问题的重点是:如何允许将

动态大小的数组作为字段*并且*保持平坦状态。 acess property。

存在什么样的更好的解决方案。你想到的吗?


谢谢


Stephane Letz

The whole point of the initial question was: how to allow to have a
dynamic sized array as a field *and* keep the "flat" acess property.
What kind of "much better solutions exist" are you thinking of?

Thanks

Stephane Letz


这篇关于关于使用“安置”的问题新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆