Content deleted Content added
PeterSymonds (talk | contribs) →References: convert reflist |
Citation bot (talk | contribs) Removed URL that duplicated identifier. | Use this bot. Report bugs. | Suggested by Headbomb | Linked from Wikipedia:WikiProject_Academic_Journals/Journals_cited_by_Wikipedia/Sandbox | #UCB_webform_linked 104/967 |
||
(92 intermediate revisions by 62 users not shown) | |||
Line 1:
In the [[C++]] [[programming language]], '''placement [[Syntax (programming languages)|syntax]]''' allows programmers to explicitly specify the [[memory management]] of individual objects — i.e. their "placement" in [[memory (computing)|memory]]. Normally, when an object is created dynamically, an allocation function is invoked in such a way that it will both allocate memory for the object, and [[Constructor (object-oriented programming)|initialize]] the object within the newly allocated memory.<!--5.3.5--> The placement syntax allows the programmer to supply additional arguments to the allocation function. A common use is to supply a [[pointer (computer programming)|pointer]] to a suitable region of storage where the object can be initialized, thus separating memory allocation from object construction.{{Citation needed|date=October 2010}}
The "placement" versions of the <code>[[new (C++)|new]]</code> and <code>[[delete (C++)|delete]]</code> operators and functions are known as placement <code>new</code> and placement <code>delete</code>.<ref name=McCluskey2000 /> A <code>new</code> ''expression'', placement or otherwise, calls a <code>new</code> ''function'', also known as an allocator function, whose name is <code>operator new</code>.
Any <code>new</code> expression that uses the placement syntax is a placement <code>new</code> expression, and any <code>operator new</code> or <code>operator delete</code> function that takes more than the mandatory first parameter (<
== History ==
In earlier versions of C++, there was no such thing as ''placement new''; instead, developers used explicit assignment to <code>this</code> within constructors to achieve similar effect.<ref name=Stroustrup1991 /> This practice has been deprecated and abolished later,{{When|date=April 2025 |reason=Is there a specific C++ standard that abolishes this technique?}} and the third edition of ''[[The C++ Programming Language]]'' does not mention this technique.
== Expressions ==
The Standard C++ syntax for a non-placement <code>new</code> expression is<ref name=Lischner2003 />
: <code>new ''new-type-id'' ( ''optional-initializer-expression-list'' )</code>
The placement syntax adds an expression list immediately after the <code>new</code> keyword. This expression list is the placement. It can contain any number of expressions.<ref name=Lischner2003 /><ref name=Lippman1997 /><ref name=Loudon2003 />
: <code>new ( ''expression-list'' ) ''new-type-id'' ( ''optional-initializer-expression-list'' )</code>
== Functions ==
The placement new functions are overloads of the non-placement new functions.
void
void
</syntaxhighlight>
The Standard C++ library provides two placement overloads each for these functions.
void
void
void
void
</syntaxhighlight>
In all of the overloads, the first parameter to the <code>operator new</code> function is of type <
There are also placement delete functions.
void operator delete
void operator delete[]
</syntaxhighlight>
The Standard C++ library provides two placement overloads each for these functions.
void operator delete
void operator delete
void operator delete[]
void operator delete[]
</syntaxhighlight>
In all of the overloads, the first parameter to the <code>operator delete</code> function is of type <
For both the new and the delete functions, the functions are global, are not in any namespace, and do not have static linkage.<ref name=
== Use ==
Placement syntax has four main uses: default placement, preventing exceptions, custom allocators, and debugging.
=== Default placement ===
The placement overloads of <code>operator new</code> and <code>operator delete</code> that employ an additional <
void
void
void operator delete
void operator delete[]
</syntaxhighlight>
There are various uses for default placement.
[[Bjarne Stroustrup]] originally observed, in his book ''The Design and Evolution of C++'', that pointer placement new is necessary for hardware that expects a certain object at a specific hardware address. It is also required for the construction of objects that need to reside in a certain memory area, such as an area that is shared between several processors of a multiprocessor computer.<ref name=
Other uses, however, include calling a constructor directly, something which the C++ language does not otherwise permit.<ref name=Lippman1997 />
The C++ language does allow a program to call a [[destructor (computer science)|destructor]] directly, and, since it is not possible to destroy the object using a <code>delete</code> expression, that is how one destroys an object that was constructed via a pointer placement new expression. For example:<ref name=SolterKleper2005 /><ref name=SeedCooper2001 />
<syntaxhighlight lang="cpp">
p->~T();
</syntaxhighlight>
=== Use cases ===
Placement new is used when you do not want operator new to allocate memory (you have pre-allocated it and you want to place the object there), but you do want the object to be constructed. Examples of typical situations where this may be required are:
* You want to create objects in memory shared between two different processes.
* You want objects to be created in non-pageable memory.
* You want to separate memory allocation from construction e.g. in implementing a <code>std::vector<></code> (see <code>std::vector<>::reserve</code>).
The basic problem is that the constructor is a peculiar function; when it starts off, there is no object, only raw memory. And by the time it finishes, you have a fully initialized object. Therefore, i) The constructor cannot be called on an object ii) However, it needs to access (and initialize) non-static members. This makes calling the constructor directly an error. The solution is the placement form of operator new.
This operator is implemented as:
<syntaxhighlight lang="cpp">
void* operator new(std::size_t count, void* here) noexcept { return here; }
void* operator new[](std::size_t count, void* here) noexcept { return here; }
</syntaxhighlight>
=== Preventing exceptions ===
Normally, the (non-placement) new functions throw an exception, of type <code>std::bad_alloc</code>, if they encounter an error, such as exhaustion of all available memory.
Programmers
import std;
struct T {}
int main
// Call the function operator new(std::size_t, const std::nothrow_t&) and (if successful) construct the object.
T* p = new (std::nothrow) T;
if (p) {
// The storage has been allocated and the constructor called.
delete p
} else
; // An error has occurred. No storage has been allocated and no object constructed.
return 0
}
</syntaxhighlight>
=== Custom allocators ===
Placement syntax is also employed for custom [[allocator (C++)|allocators]].
import std;
class A {
public:
void
void deallocate
}
</syntaxhighlight>
And define custom placement allocation and deallocation functions as follows:<ref name=
void* operator new(std::size_t size, A& arena) {
return arena.allocate(size);
}
void operator delete
arena.deallocate(p);
}
</syntaxhighlight>
The program would employ the placement syntax to allocate objects using different instances of the <code>A</code> class as follows:<ref name=
A first_arena, second_arena
T
T
</syntaxhighlight>
Destroying an object whose storage is allocated in such a fashion requires some care.
The former would resemble:<ref name=
void destroy(T* p, A& arena) {
p->~T(); // First invoke the destructor explicitly.
arena.deallocate(p); // Then call the deallocator function directly.
}
</syntaxhighlight>
which would be invoked from a program as:
A arena
T
/* ... */
destroy(p, arena)
</syntaxhighlight>
The latter would involve simply writing the destructor invocation and delete function call into the program:<ref name=
A arena
T
/* ... */
p->~T()
operator delete(p, arena)
</syntaxhighlight>
A common error is to attempt to use a delete expression to delete the object.
=== Debugging ===
Placement new can also be used as a simple debugging tool, to enable programs to print the filename and line number of the source code where a memory allocation has failed.
#if defined(DEBUG_NEW)
void
void
void operator delete
void operator delete[]
#define New new(__FILE__, __LINE__)
#else
#define New new
#endif
</syntaxhighlight>
This would be employed in a program as follows:<ref name=
T
</syntaxhighlight>
The custom-written placement new functions would then handle using the supplied file and line number information in the event of an exception.
import std;
class
public:
/* ... */
} ;
void* operator new(std::size_t size, const char* file, int line) {
if (void* p = ::operator new(size, std::nothrow))
return p;
throw AlloationError(file, line);
}
</syntaxhighlight>
== Placement delete ==
As noted above, there is no placement delete expression.
The placement delete functions are called from placement <code>new</code> expressions.
The placement delete function that is called matches the placement new function that was invoked by the placement new expression.
import std;
struct A {}
struct E {}
class T {
public:
T() { throw E()
}
void
std::println("Placement new called.");
}
void operator delete(void*, const A&) {
std::println("Placement delete called.");
}
int main(){
A a;
try {
T* p = new(a) T;
} catch (E exp) {
std::println("Exception caught.");
}
return 0;
}
</syntaxhighlight>
This is why the ''pointer placement'' delete functions are defined as no-operations by the Standard C++ library. Since the pointer placement new functions do not allocate any storage, there is no storage to <ref name=":0">{{Cite book|last1=Kundu|first1=Ashish|last2=Bertino|first2=Elisa|title=2011 31st International Conference on Distributed Computing Systems |chapter=A New Class of Buffer Overflow Attacks |date=June 2011|pages=730–739|doi=10.1109/ICDCS.2011.63|isbn=978-1-61284-384-1 |s2cid=8583476 |via=IEEE}}</ref> be deallocated in the event of the object's constructor throwing an exception.<ref name=SolterKleper2005 />
If no matching placement delete function exists, no deallocation function is called in the event of an exception being thrown by a constructor within a placement <code>new</code> expression. There are also some (older) C++ implementations that do not support placement delete (which, like the exception-throwing allocator functions, were an addition made to C++ when it was standardized) at all. In both such situations, an exception being thrown by a constructor when allocating using a custom allocator will result in a memory leak. (In the case of the older C++ implementations, a memory leak will also occur with ''non-''placement <code>new</code> expressions.)<ref name=Meyers1998 /><ref name=Anderson1998b />
== Security ==
Placement new expressions are vulnerable to security exploits. In 2011, Kundu and Bertino<ref name=":0" /> demonstrated some of the exploits on placement new. Some of the attacks are buffer overflow attacks, object overflow, selective stackguard overriding, virtual pointer subterfuge, memory misalignment attacks. In 2015, GCC released a patch<ref>{{Cite web|title=Martin Sebor - [PING] [PATCH] c++/67942 - diagnose placement new buffer overflow|url=https://gcc.gnu.org/legacy-ml/gcc-patches/2015-10/msg02001.html|access-date=2020-06-15|website=gcc.gnu.org}}</ref> based on the findings in.<ref name=":0" />
== Notes ==
{{reflist|3|refs=
<ref name=Anderson1998a>{{harvnb|Anderson|1998a|pp=345–356}}</ref>
<ref name=Anderson1998b>{{harvnb|Anderson|1998b|pp=631–632}}</ref>
<!-- <ref name=Buck1997>{{harvnb|Buck|1997}}</ref> -->
<ref name=Dewhurst2003>{{harvnb|Dewhurst|2003|pp=173–176}}</ref>
<ref name=Lischner2003>{{harvnb|Lischner|2003|pp=72–73,128–129,310, 623–625}}</ref>
<ref name=Lippman1997>{{harvnb|Lippman|1997|pp=386–389}}</ref>
<ref name=Loudon2003>{{harvnb|Loudon|2003|pp=109–110}}</ref>
<ref name=McCluskey2000>{{harvnb|McCluskey|2000}}</ref>
<ref name=Meyers1998>{{harvnb|Meyers|1998}}</ref>
<ref name=SeedCooper2001>{{harvnb|Seed|Cooper|2001|pp=435–436}}</ref>
<ref name=SolterKleper2005>{{harvnb|Solter|Kleper|2005|pp=458–461}}</ref>
<ref name=Stroustrup1991>{{harvnb|Stroustrup|1991|pp=}}{{Page needed|date=November 2010}}</ref>
<ref name=Stroustrup1994>{{harvnb|Stroustrup|1994|pp=214}}</ref>
<ref name=Stroustrup1997b>{{harvnb|Stroustrup|1997|pp=255–256, 576}}</ref>
<ref name=Vermeir2001>{{harvnb|Vermeir|2001|pp=113–115}}</ref>
<ref name=Yongwei2007>{{harvnb|Yongwei|2007}}</ref>
}}
== References ==
{{
* {{cite book|title=Navigating C++ and Object-oriented Design|first=Gail|last=Anderson|chapter=Object Storage Management|publisher=Prentice Hall|year=1998a|isbn=9780135327487}}
* {{cite book|title=Navigating C++ and Object-oriented Design|first=Gail|last=Anderson|chapter=Exception Handling|publisher=Prentice Hall|year=1998b|isbn=9780135327487}}
* {{cite web|url=http://www.desy.de/user/projects/C++/g++faq/placement_new_syntax.html|title=3.4. g++ won't accept the placement new syntax.|date=1997-05-12|first=Joe|last=Buck|work=Frequently asked questions about the GNU C++ compiler|access-date=2008-11-26}}
* {{cite book|title=C++ Gotchas|first=Stephen C.|last=Dewhurst|chapter=Gotcha #62: Replacing Global New and Delete|chapter-url=http://informit.com/articles/article.aspx?p=30642&seqNum=3|publisher=[[Addison-Wesley]]|year=2003|isbn=978-0-321-12518-7}}
* {{cite book|title=C++ in a Nutshell|first=Ray|last=Lischner|publisher=O'Reilly|year=2003|isbn=9780596002985}}
* {{cite book|title=C++ Gems|first=Stanley B.|last=Lippman|author-link= Stanley B. Lippman |publisher=Cambridge University Press|year=1997|isbn=9780135705810}}
* {{cite book|title=C++ Pocket Reference|first=Kyle|last=Loudon|publisher=O'Reilly|year=2003 |isbn=9780596004965}}
* {{cite web|ref=CITEREFMcCluskey2000|url=http://glenmccl.com/nd_cmp.htm|title=Placement New/Delete|publisher=Glen McCluskey & Associates LLC|work=C++ Language and Library|date=2000-06-26|access-date=2008-11-26|url-status=dead|archive-url=https://web.archive.org/web/20060418093041/http://www.glenmccl.com/nd_cmp.htm|archive-date=2006-04-18}}
* {{cite news|date=1998-04-01|first=Scott|last=Meyers|title=Placement new and placement delete|url=http://ddj.com/showArticle.jhtml?documentID=cuj9804meyers&pgno=2|work=[[Dr. Dobb's Journal]]|publisher=United Business Media LLC}}
* {{cite book|title=An Introduction to Object-oriented Programming in C++|first1=Graham M.|last1=Seed|first2=Barry J.|last2=Cooper|publisher=Springer|year=2001|isbn=1-85233-450-9|edition=Second}}
* {{cite book|title=Professional C++|first1=Nicholas|last1=Solter|first2=Scott|last2=Kleper|publisher=Wiley|year=2005|isbn=9780764574849}}
* {{cite book|title=The C++ Programming Language|edition=2nd|first=Bjarne|last=Stroustrup|author-link=Bjarne Stroustrup|isbn=978-0-201-53992-9|date=July 1991|publisher=Pearson Education Canada |url-access=registration|url=https://archive.org/details/cprogramminglang00stro}}
* {{cite book|last=Stroustrup|first=Bjarne|author-link=Bjarne Stroustrup|title=Design and Evolution of C++|publisher=[[Addison-Wesley]]|isbn=978-0-201-54330-8|year=1994|chapter=Memory Management}}
* {{cite book|last=Stroustrup|first=Bjarne|author-link=Bjarne Stroustrup|title=The C++ Programming Language|publisher=[[Addison-Wesley]]|edition=3rd|isbn=978-0-201-88954-3|year=1997|url-access=registration|url=https://archive.org/details/cprogramminglang00stro_0}}
* {{cite book|title=Multi-paradigm Programming Using C++|first=Dirk|last=Vermeir|publisher=Springer|year=2001|isbn=9781852334833}}
* {{cite web|title=A Cross-Platform Memory Leak Detector|date=2007-12-31|first=Wu|last=Yongwei|access-date=2008-11-26|work=Wu Yongwei's Programming Page|url=http://wyw.dcweb.cn/leakage.htm}}
{{refend}}
== Further reading ==
* {{cite book|last=Franek|first=Frantisek|title=Memory as a Programming Concept in C and C++|publisher=[[Cambridge University Press]]|isbn=
* {{cite web|title=11.10: What is "placement new" and why would I use it?|url=http://parashift.com./c++-faq-lite/dtors.html#faq-11.10|work=C++ FAQ Lite|date=
* {{cite web|url=http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/topic/com.ibm.vacpp6m.doc/language/ref/clrc05cplr199.htm|title=C++ new Operator|work=IBM's Mac OS X compilers|
* {{cite web|url=http://msdn.microsoft.com/en-us/library/t48aek43.aspx|work=[[MSDN]]|title=The operator new Function|publisher=[[Microsoft]]|access-date=
* {{cite web|url=http://msdn.microsoft.com/en-us/library/kewsb8ba.aspx|work=[[MSDN]]|title=new Operator (C++)|publisher=[[Microsoft]]|access-date=
{{DEFAULTSORT:Placement Syntax}}
[[Category:Articles with example C++ code]]
[[Category:C++]]
|