Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Smart pointer
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
{{short description|Data type simulating a pointer with additional features}} {{more citations needed|date=June 2015}} {{use dmy dates|date=July 2022|cs1-dates=y}} {{use list-defined references|date=July 2022}} In [[computer science]], a '''smart pointer''' is an [[abstract data type]] that simulates a [[Pointer (computer programming)|pointer]] while providing added features, such as automatic [[memory management]] or [[bounds checking]]. Such features are intended to reduce [[Software bug|bugs]] caused by the misuse of pointers, while retaining efficiency. Smart pointers typically keep track of the memory they point to, and may also be used to manage other resources, such as network connections and [[file handle]]s. Smart pointers were first popularized in the programming language [[C++]] during the first half of the 1990s as rebuttal to criticisms of C++'s lack of [[automatic garbage collection]].<ref name="Kline_1997"/><ref name="Colvin_1994"/> Pointer misuse can be a major source of bugs. Smart pointers prevent most situations of [[memory leak]]s by making the memory deallocation automatic. More generally, they make [[object destruction]] automatic: an object controlled by a smart pointer is automatically destroyed ([[finalization|finalized]] and then deallocated) when the last (or only) owner of an object is destroyed, for example because the owner is a [[local variable]], and execution leaves the variable's [[scope (programming)|scope]]. Smart pointers also eliminate [[dangling pointer]]s by postponing destruction until an object is no longer in use. If a language supports automatic garbage collection (for example, [[Java (programming language)|Java]] or [[C Sharp (programming language)|C#]]), then smart pointers are unneeded for reclaiming and safety aspects of memory management, yet are useful for other purposes, such as [[Cache (computing)|cache]] data structure residence management and [[resource management]] of objects such as file handles or [[network socket]]s. Several types of smart pointers exist. Some work with [[reference counting]], others by assigning ownership of an object to one pointer. == History == Even though C++ popularized the concept of smart pointers, especially the [[Reference counting|reference-counted]] variety,<ref name="Klabnik-Nichols_2023"/> the immediate predecessor of one of the languages that inspired C++'s design had reference-counted references built into the language. C++ was inspired in part by [[Simula67]].<ref name="Stroustrup"/> Simula67's ancestor was [[Simula I]]. Insofar as Simula I's ''element'' is analogous to C++'s pointer without ''null'', and insofar as Simula I's process with a dummy-statement as its activity body is analogous to C++'s ''struct'' (which itself is analogous to [[C. A. R. Hoare]]'s ''record'' in then-contemporary 1960s work), Simula I had reference counted elements (i.e., pointer-expressions that house indirection) to processes (i.e., records) no later than September 1965, as shown in the quoted paragraphs below.<ref name="Dahl-Nygaard_1966"/> <blockquote> Processes can be referenced individually. Physically, a process reference is a pointer to an area of memory containing the data local to the process and some additional information defining its current state of execution. However, for reasons stated in the Section 2.2 process references are always indirect, through items called ''elements.'' Formally a reference to a process is the value of an expression of type ''element''.<br> …<br> ''element'' values can be stored and retrieved by assignments and references to ''element'' variables and by other means.<br> The language contains a mechanism for making the attributes of a process accessible from the outside, i.e., from within other processes. This is called remote access- ing. A process is thus a referenceable data structure.<br> It is worth noticing the similarity between a process whose activity body is a dummy statement, and the record concept recently proposed by C. A. R. Hoare and [[Niklaus Wirth|N. Wirth]]</blockquote> Because C++ borrowed [[Simula]]'s approach to memory allocation{{Em dash}}the ''new'' keyword when allocating a process/record to obtain a fresh ''element'' to that process/record{{Em dash}}it is not surprising that C++ eventually resurrected Simula's reference-counted smart-pointer mechanism within ''element'' as well. == Features == In [[C++]], a smart pointer is implemented as a template class that mimics, by means of [[operator overloading]], the behaviors of a traditional [[Raw pointer|(raw) pointer]], (e.g. dereferencing, assignment) while providing additional memory management features. Smart pointers can facilitate intentional programming by expressing, in the type, how the memory of the referent of the pointer will be managed. For example, if a C++ function returns a pointer, there is no way to know whether the caller should delete the memory of the referent when the caller is finished with the information. <syntaxhighlight lang="cpp"> SomeType* AmbiguousFunction(); // What should be done with the result? </syntaxhighlight> Traditionally, naming conventions have been used to resolve the ambiguity,<ref name="Taligent"/> which is an error-prone, labor-intensive approach. [[C++11]] introduced a way to ensure correct memory management in this case by declaring the function to return a <code>unique_ptr</code>, <syntaxhighlight lang="cpp"> std::unique_ptr<SomeType> ObviousFunction(); </syntaxhighlight> The declaration of the function return type as a <code>unique_ptr</code> makes explicit the fact that the caller takes ownership of the result, and the C++ runtime ensures that the memory will be reclaimed automatically. Before [[C++11]], unique_ptr can be replaced with [[auto_ptr]], which is now deprecated. == Creating new objects == To ease the allocation of a <syntaxhighlight lang="cpp">std::shared_ptr<SomeType></syntaxhighlight>[[C++11]] introduced: <syntaxhighlight lang="cpp"> auto s = std::make_shared<SomeType>(constructor, parameters, here); </syntaxhighlight> and similarly <syntaxhighlight lang="cpp">std::unique_ptr<some_type></syntaxhighlight>Since [[C++14]] one can use: <syntaxhighlight lang="cpp"> auto u = std::make_unique<SomeType>(constructor, parameters, here); </syntaxhighlight> It is preferred, in almost all circumstances, to use these facilities over the <code>new</code> keyword.<ref name="Sutter_2013"/> == unique_ptr == [[C++11]] introduces {{code|std::unique_ptr}}, defined in the header {{code|<memory>}}.<ref name="ISO14882_2011"/> A {{code|unique_ptr}} is a container for a raw pointer, which the <code>unique_ptr</code> is said to own. A <code>unique_ptr</code> explicitly prevents copying of its contained pointer (as would happen with normal assignment), but the {{code|std::move}} function can be used to transfer ownership of the contained pointer to another {{code|unique_ptr}}. A <code>unique_ptr</code> cannot be copied because its copy constructor and assignment operators are explicitly deleted. <syntaxhighlight lang="cpp"> std::unique_ptr<int> p1(new int(5)); std::unique_ptr<int> p2 = p1; // Compile error. std::unique_ptr<int> p3 = std::move(p1); // Transfers ownership. p3 now owns the memory and p1 is set to nullptr. p3.reset(); // Deletes the memory. p1.reset(); // Does nothing. </syntaxhighlight> <code>std::[[auto_ptr]]</code> is [[Deprecation|deprecated]] under C++11 and completely removed from [[C++17]]. The copy constructor and assignment operators of {{code|auto_ptr}} do not actually copy the stored pointer. Instead, they [[Auto ptr#Semantics|transfer it]], leaving the prior {{code|auto_ptr}} object empty. This was one way to implement strict ownership, so that only one {{code|auto_ptr}} object can own the pointer at any given time. This means that {{code|auto_ptr}} should not be used where copy semantics are needed.<ref name="CERT"/>{{citation needed|date=September 2016}} Since {{code|auto_ptr}} already existed with its copy semantics, it could not be upgraded to be a move-only pointer without breaking [[backward compatibility]] with existing code. == shared_ptr and weak_ptr == C++11 introduces {{code|std::shared_ptr}} and {{code|std::weak_ptr}}, defined in the header {{code|<memory>}}.<ref name="ISO14882_2011"/> C++11 also introduces {{Code|std::make_shared}} ({{Code|std::make_unique}} was introduced in C++14) to safely allocate dynamic memory in the [[Resource acquisition is initialization|RAII]] paradigm.<ref name="ISO14882_2014"/> A {{code|shared_ptr}} is a container for a [[raw pointer]]. It maintains [[reference counting]] ownership of its contained pointer in cooperation with all copies of the {{code|shared_ptr}}. An object referenced by the contained raw pointer will be destroyed when and only when all copies of the {{code|shared_ptr}} have been destroyed. <syntaxhighlight lang="cpp"> std::shared_ptr<int> p0(new int(5)); // Valid, allocates 1 integer and initialize it with value 5. std::shared_ptr<int[]> p1(new int[5]); // Valid, allocates 5 integers. std::shared_ptr<int[]> p2 = p1; // Both now own the memory. p1.reset(); // Memory still exists, due to p2. p2.reset(); // Frees the memory, since no one else owns the memory. </syntaxhighlight> A {{code|weak_ptr}} is a container for a raw pointer. It is created as a copy of a <code>shared_ptr</code>. The existence or destruction of {{code|weak_ptr}} copies of a <code>shared_ptr</code> have no effect on the <code>shared_ptr</code> or its other copies. After all copies of a <code>shared_ptr</code> have been destroyed, all <code>weak_ptr</code> copies become empty. <syntaxhighlight lang="cpp"> std::shared_ptr<int> p1 = std::make_shared<int>(5); std::weak_ptr<int> wp1 {p1}; // p1 owns the memory. { std::shared_ptr<int> p2 = wp1.lock(); // Now p1 and p2 own the memory. // p2 is initialized from a weak pointer, so you have to check if the // memory still exists! if (p2) { DoSomethingWith(p2); } } // p2 is destroyed. Memory is owned by p1. p1.reset(); // Free the memory. std::shared_ptr<int> p3 = wp1.lock(); // Memory is gone, so we get an empty shared_ptr. if (p3) { // code will not execute ActionThatNeedsALivePointer(p3); } </syntaxhighlight> Because the implementation of {{code|shared_ptr}} uses [[reference counting]], [[Reference count#Dealing with reference cycles|circular references]] are potentially a problem. A circular <code>shared_ptr</code> chain can be broken by changing the code so that one of the references is a <code>weak_ptr</code>. Multiple threads can safely simultaneously access different {{code|shared_ptr}} and {{code|weak_ptr}} objects that point to the same object.<ref name="Boost"/> The referenced object must be protected separately to ensure [[thread safety]]. {{code|shared_ptr}} and {{code|weak_ptr}} are based on versions used by the [[Boost (C++ libraries)|Boost libraries]].{{citation needed|date=January 2014}} [[C++ Technical Report 1]] (TR1) first introduced them to the standard, as [[C++ Technical Report 1#General utilities|general utilities]], but C++11 adds more functions, in line with the Boost version. == Other types of smart pointers == There are other types of smart pointers (which are not in the C++ standard) implemented on popular C++ libraries or custom [[Standard Template Library|STL]], some examples include [[hazard pointer]]<ref>{{cite web|url=https://github.com/facebook/folly/blob/main/folly/synchronization/Hazptr.h|title=folly/Hazptr.h at main · facebook/folly|website=github.com}}</ref> and intrusive pointer.<ref>{{cite web|url=https://www.boost.org/doc/libs/1_81_0/libs/smart_ptr/doc/html/smart_ptr.html|title=Boost.SmartPtr: The Smart Pointer Library - 1.81.0|website=boost.org}}</ref><ref>{{cite web|url=https://github.com/electronicarts/EASTL/blob/master/include/EASTL/intrusive_ptr.h|title=EASTL/intrusive_ptr.h at master · electronicarts/EASTL|website=github.com}}</ref> == See also == * [[auto_ptr]] * [[Fat pointer]] * [[Tagged pointer]] * [[Opaque pointer]] * [[Reference (computer science)]] * [[Boost (C++ libraries)]] * [[Automatic Reference Counting]] * [[Resource acquisition is initialization]] (RAII) * [[Garbage collection (computer science)|Garbage collection]] in computer programming == References == {{Reflist|refs= <ref name="Kline_1997">{{cite web |url=http://www.cis.usouthal.edu/faculty/drh/c%2B%2Bfaq/freestore-mgmt.html#[16.20 |title=C++ FAQs Lite's sections on reference-counted smart pointers and copy-on-write reference semantics in the freestore management FAQs |author-last=Kline |author-first=Marshall |date=September 1997 |website=cis.usouthal.edu |access-date=2018-04-06}}</ref> <ref name="Colvin_1994">{{cite web |url=http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1994/N0555.pdf |title=proposal to standardize counted_ptr in the C++ standard library |author-last=Colvin |author-first=Gregory |date=1994 |website=open-std.org |access-date=2018-04-06}}</ref> <ref name="Stroustrup">{{cite web |url=http://www.stroustrup.com/hopl2.pdf |author-last=Stroustrup |author-first=Bjarne |title=A history of C++: 1979–1991 |access-date=2018-04-06}}</ref> <ref name="Dahl-Nygaard_1966">{{cite web |url=http://folk.uio.no/simula67/Archive/artikkel1966cacm.pdf |author-last1=Dahl |author-first1=Ole-Johan |author-last2=Nygaard |author-first2=Kristen |title=SIMULA—An ALGOL-based simulation language |date=September 1966 |website=folk.uio.no |access-date=2018-04-06}}</ref> <ref name="Taligent">{{cite web |url=https://root.cern.ch/TaligentDocs/TaligentOnline/DocumentRoot/1.0/Docs/books/WM/WM_67.html#HEADING81 |title=Taligent's Guide to Designing Programs, section Use special names for copy, create, and adopt routines}}</ref> <ref name="Sutter_2013">{{cite web |author-last=Sutter |author-first=Herb |author-link=Herb Sutter |title=Trip Report: ISO C++ Spring 2013 Meeting |url=http://isocpp.org/blog/2013/04/trip-report-iso-c-spring-2013-meeting |date=2013-04-20 |website=isocpp.org |access-date=2013-06-14}}</ref> <ref name="ISO14882_2011">ISO 14882:2011 20.7.1</ref> <ref name="CERT">CERT C++ Secure Coding Standard</ref> <ref name="ISO14882_2014">ISO 14882:2014 20.7.1</ref> <ref name="Boost">{{cite web |url=http://www.boost.org/libs/smart_ptr/shared_ptr.htm#ThreadSafety |title=boost::shared_ptr thread safety}} (NB. Does not formally cover std::shared_ptr, but is believed to have the same threading limitations.)</ref> <ref name="Klabnik-Nichols_2023">{{cite book |title=The Rust Programming Language |chapter=15. Smart Pointers |date=2023 |orig-date=2018<!-- 1st edition --> |edition=2 |author-first1=Steve |author-last1=Klabnik |author-first2=Carol |author-last2=Nichols |publisher=[[No Starch Press, Inc.]] |publication-place=San Francisco, California, USA |isbn=978-1-7185-0310-6 <!-- |lccn=1st edition: 2018014097 --> |pages=315–351 }} (xxix+1+527+3 pages)</ref> }} == Further reading == * {{cite book |title=Effective Modern C++ |author-first=Scott |author-last=Meyers |author-link=Scott Meyers |publisher=[[O'Reilly Media]] |date=2014 |isbn=978-1-49190399-5 |location=Sebastopol, California, USA |oclc=884480640}} * {{cite book |chapter-url=http://www.informit.com/articles/article.aspx?p=25264 |chapter=Smart Pointers |title=Modern C++ Design - Generic Programming and Design Patterns Applied |title-link=Modern C++ Design |author-first=Andrei |author-last=Alexandrescu |author-link=Andrei Alexandrescu |publisher=[[Addison-Wesley]] |date=2001}} * {{cite web |url=http://www.drdobbs.com/184403837/ |title=The New C++: Smart(er) Pointers |author-first=Herb |author-last=Sutter |author-link=Herb Sutter |date=2002-08-01}} * [http://ootips.org/yonat/4dev/smart-pointers.html Smart Pointers - What, Why, Which?]. Yonat Sharon * [http://dlugosz.com/Repertoire/refman/Classics/Smart%20Pointers%20Overview.html Smart Pointers Overview]. John M. Dlugosz == External links == * [http://www.josuttis.com/libbook/cont/countptr.hpp.html countptr.hpp]. ''[http://www.josuttis.com/libbook/ The C++ Standard Library - A Tutorial and Reference]'' by Nicolai M. Josuttis * [http://boost.org/libs/smart_ptr/smart_ptr.htm Boost Smart Pointers] * [http://barrkel.blogspot.com/2008/09/smart-pointers-in-delphi.html Smart Pointers in Delphi] * [https://doc.rust-lang.org/book/ch15-00-smart-pointers.html Smart Pointers in Rust] * [http://quant-coder.blogspot.com/2015/12/built-in-smart-pointers-in-modern-c.html Smart Pointers in Modern C++] [[Category:Articles with example C++ code]] [[Category:Data types]] [[Category:Pointers (computer programming)]]
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)
Pages transcluded onto the current version of this page
(
help
)
:
Template:Citation needed
(
edit
)
Template:Cite book
(
edit
)
Template:Cite web
(
edit
)
Template:Code
(
edit
)
Template:Em dash
(
edit
)
Template:More citations needed
(
edit
)
Template:Reflist
(
edit
)
Template:Short description
(
edit
)
Template:Use dmy dates
(
edit
)
Template:Use list-defined references
(
edit
)