C++ 有什么用途? 构建“新的展示位置”?
我刚刚了解了名为“placement new”的 C++ 结构。 它允许您精确控制指针在内存中指向的位置。 它看起来像这样:(
#include <new> // Must #include this to use "placement new"
#include "Fred.h" // Declaration of class Fred
void someCode()
{
char memory[sizeof(Fred)];
void* place = memory;
Fred* f = new(place) Fred(); // Create a pointer to a Fred(),
// stored at "place"
// The pointers f and place will be equal
...
}
来自 的示例C++ FAQ Lite)
在此示例中,Fred 的 this
指针将等于 place
。
我在我们团队的代码中见过它一两次。 根据您的经验,这个结构可以实现什么? 其他指针语言是否有类似的结构? 对我来说,这似乎让人想起 FORTRAN 中的等价
,它允许不同的变量占据内存中的相同位置。
I just learned about the C++ construct called "placement new". It allows you to exactly control where a pointer points to in memory. It looks like this:
#include <new> // Must #include this to use "placement new"
#include "Fred.h" // Declaration of class Fred
void someCode()
{
char memory[sizeof(Fred)];
void* place = memory;
Fred* f = new(place) Fred(); // Create a pointer to a Fred(),
// stored at "place"
// The pointers f and place will be equal
...
}
(example from C++ FAQ Lite)
In this example, the this
pointer of Fred will be equal to place
.
I've seen it used in our team's code once or twice. In your experience, what does this construct enable? Do other pointer languages have similar constructs? To me, it seems reminiscent of equivalence
in FORTRAN, which allows disparate variables to occupy the same location in memory.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
当将内存调出到硬盘驱动器上的文件时(在操作大型对象时可能会这样做),它会很有用。
It can be useful when paging out memory to a file on the hard drive, which one might do when manipulating large objects.
Placement new 允许开发人员从预分配的内存块中分配内存。 如果系统更大,那么开发人员会选择使用新的布局。 现在我正在开发一个更大的航空电子软件,我们在开始时分配执行应用程序所需的大内存。 我们使用placement new 来在需要的地方分配内存。 它将性能提高到一定程度。
Placement new allows the developer to allocate the memory from preallocated memory chunk. If the system is larger, then developers go for using placement new. Now I am working on a larger avionics software there we allocate the large memory that is required for the execution of application at the start. And we use the placement new to allocate the memory wherever required. It increases the performance to some amount.
在我看来,这就像一种在堆栈上分配对象的方法..
seems to me like a way of allocating an object on the stack ..
我用它来基于包含从网络接收到的消息的内存来创建对象。
I've used it to create objects based on memory containing messages received from the network.
它允许您进行自己的内存管理。 通常这最多只能让你的性能略有提高,但有时这是一个巨大的胜利。 例如,如果您的程序使用大量标准大小的对象,您可能很想创建一个具有较大内存分配的池。
此类事情也在 C 中完成,但由于 C 中没有构造函数,因此不需要任何语言支持。
It allows you to do your own memory management. Usually this will get you at best marginally improved performance, but sometimes it's a big win. For example, if your program is using a large number of standard-sized objects, you might well want to make a pool with one large memory allocation.
This sort of thing was also done in C, but since there are no constructors in C it didn't require any language support.
它还用于嵌入式编程,其中 IO 设备通常映射到特定的内存地址
It is also used for embedded programming, where IO devices are often mapped to specific memory addresses
在构建您自己的容器(如对象)时,它很有用。
例如,如果您要创建一个向量。 如果您为大量对象保留空间,则希望使用某种不调用对象构造函数的方法来分配内存(例如 new char[sizeof(object) * ReserveSize])。 然后,当人们开始将对象添加到向量中时,您可以使用placement new将它们复制到分配的内存中。
附言。 我并不提倡这样做。 这只是容器如何工作的一个简化示例。
Its usefull when building your own container like objects.
For example if you were to create a vector. If you reserve space for a large number of objects you want to allocate the memory with some method that does not invoke the constructor of the object (like new char[sizeof(object) * reserveSize]). Then when people start adding objects into the vector you use placement new to copy them into allocated memory.
PS. I am not advocating doing this. This is just a simplified example of how containers can work.
我在共享内存段中构造对象时使用了它。
I've used it when constructing objects in a shared memory segment.
放置 new 可用于创建类型安全的联合,例如 Boost 的
variant
。联合类包含一个与指定它包含的最大类型一样大的缓冲区(并且具有足够的对齐)。 它根据需要将 new 对象放置到缓冲区中。
Placement new can be used to create type-safe unions, such as Boost's
variant
.The union class contains a buffer as big as the biggest type it's specified to contain (and with sufficient alignment). It placement
new
s objects into the buffer as required.我在内核模式下执行 C++ 时使用此构造。
我使用内核模式内存分配器并在分配的块上构造对象。
所有这些都包含在类和函数中,但最后我做了一个新的放置。
I use this construct when doing C++ in kernel mode.
I use the kernel mode memory allocator and construct the object on the allocated chunk.
All of this is wrapped in classes and functions, but in the end I do a placement new.
放置 new 并不是要使指针相等(您可以为此使用赋值!)。
Placement new 用于在特定位置构造对象。 在 C++ 中构造对象的方法有三种,而放置 new 是唯一一种可以让您显式控制该对象“存在”的位置的方法。 这对于很多事情都很有用,包括共享内存、低级设备 I/O 和内存池/分配器实现。
通过堆栈分配,对象将在堆栈顶部构造,无论当前位于堆栈顶部。
使用“常规”new,该对象是在堆上的有效任意地址处构造的,由标准库管理(除非您覆盖了operator new)。
放置 new 表示“专门在这个地址为我构建一个对象”,它的实现只是运算符 new 的重载,它返回传递给它的指针,作为获取 new 运算符的其余部分的方法,该运算符构造由operator new函数返回的内存中的对象。
还值得注意的是,operator new 函数可以用任意参数重载(就像任何其他函数一样)。 这些其他参数通过“new(arg 2, arg3, ..., argN)”语法传递。 Arg1 始终作为“sizeof(无论您正在构造什么)”隐式传递。
Placement new is NOT about making pointers equal (you can just use assignment for that!).
Placement new is for constructing an object at a particular location. There are three ways of constructing an object in C++, and placement new is the only one that gives you explicit control over where that object "lives". This is useful for several things, including shared memory, low-level device I/O, and memory pool/allocator implementation.
With stack allocation, the object is constructed at the top of the stack, wherever that happens to be currently.
With "regular" new, the object is constructed at an effectively arbitrary address on the heap, as managed by the standard library (unless you've overridden operator new).
Placement new says "build me an object at this address specifically", and its implementation is simply an overload of operator new that returns the pointer passed to it, as a means of getting to the remainder of the machinery of the new operator, which constructs an object in the memory returned by the operator new function.
It's also worth noting that the operator new function can be overloaded with arbitrary arguments (just as any other function). These other arguments are passed via the "new(arg 2, arg3, ..., argN)" syntax. Arg1 is always implicitly passed as "sizeof(whatever you're constructing)".
通过控制确切的位置,您可以对齐内存中的内容,这有时可以用来提高 CPU 获取/缓存性能。
但从未真正见过它的使用
By controlling the exact placement, you can align things in memory and this can sometimes be used to improve CPU fetch/cache performance.
Never actually saw it in use, though