Module 56
Module 56
L
Partha Pratim
Das
Programming in Modern C++
E
Weekly Recap
Objectives & Module M56: C++11 and beyond: Resource Management by Smart Pointers: Part 1
T
Outlines
Raw Pointers
P
Operations
Ownership Issue
Pointers vs. Partha Pratim Das
N
Reference
Smart Pointers
Policies Department of Computer Science and Engineering
Storage Policy Indian Institute of Technology, Kharagpur
Ownership Policy
All url’s in this module have been accessed in September, 2021 and found to be functional
Module M56
• Learnt how Rvalue Reference works as a Universal Reference under template type deduction
L
Partha Pratim
Das
• Understood the problem of forwarding of parameters and its solution using Universal Reference
E
Weekly Recap and std::forward
Objectives & • Understood how Move works as an optimization of Copy
T
Outlines
• Understood λ expressions (unnamed function objects) in C++ with
Raw Pointers
◦ Closure Objects
P
Operations
Ownership Issue
Pointers vs.
◦ Parameters
N
Reference
◦ Capture
Smart Pointers
Policies
• Learnt different techniques without or with std::function to write and use non-recursive and
Storage Policy recursive λ expressions in C++11 / C++14
Ownership Policy
• Introducing several class features in C++11 with examples
Module Summary
• Explained how these features enhance OOP, generic programming, readability, type-safety, and
performance in C++11
• Introduced several features in C++11 for non-class types and templates with examples
• Familiarizes with important non-class types like enum class and fixed width integer
• Familiarized with important templates like variadic templates
Programming in Modern C++ Partha Pratim Das M56.2
Module Objectives
Module M56
L
Partha Pratim
Das
• Introduce Smart pointers with typical interface and use
E
Weekly Recap
Objectives &
• Introduce the policies for smart pointer
T
Outlines
Raw Pointers
P
Operations
Ownership Issue
Pointers vs.
N
Reference
Smart Pointers
Policies
Storage Policy
Ownership Policy
Module Summary
Module M56
L
Partha Pratim
Das 1 Weekly Recap
E
Weekly Recap
T
Outlines
Raw Pointers
Operations
Ownership Issue
P
Operations
Ownership Issue
Pointers vs.
Pointers vs. Reference
N
Reference
Smart Pointers
Policies 3 Smart Pointers
Storage Policy
Ownership Policy
Policies
Module Summary
Storage Policy
Ownership Policy
4 Module Summary
Module M56
L
Partha Pratim
Das
E
Weekly Recap
Objectives &
T
Outlines
Raw Pointers
P
Operations
Ownership Issue
Pointers vs.
N
Reference
Smart Pointers
Policies
Storage Policy
Ownership Policy
Module Summary
Raw Pointers
Sources:
• How to use C++ raw pointers properly? Sorush Khajepor, 2020
Module M56
• Imbibe a culture to write good C++ code
◦ Correct: Achieves the functionality
L
Partha Pratim
Das
◦ Bug free: Free of programming errors
◦ Maintainable: Easy to develop and support
E
Weekly Recap
T
Outlines
Raw Pointers
• Dynamic creation & destruction of objects is a strength and a bugbear of C / C++
• It needs manual resource management by the programmer. She / he has to control:
P
Operations
Ownership Issue
Pointers vs. ◦ the allocation of memory for the object,
N
Reference
Smart Pointers
◦ handle the object’s initialisation and,
Policies ◦ ensure that object was safely cleaned-up after use and its memory returned to heap
Storage Policy
Ownership Policy • This leads to C / C++ being an unsafe, memory-leaking language
Module Summary • Resource Management frees the client from having to worry about the lifetime of the
managed object, eliminating memory leaks and other problems in C++ code
• A resource could be any object that required dynamic creation/deletion – memory, files,
sockets, mutexes, etc.
• Effective Resource Management is needed so that dynamically managed objects can be
managed as automatic object
Programming in Modern C++ Partha Pratim Das M56.6
Raw Pointers: Operations
Module M56
L
Partha Pratim
Das
E
Weekly Recap
Objectives &
T
Outlines
Raw Pointers
P
Operations
Ownership Issue
Pointers vs.
N
Reference
Smart Pointers
Policies
Storage Policy
Ownership Policy
Module Summary
Raw Pointers: Operations
Module M56
L
Partha Pratim
Das
• Deallocation (called on)
E
Weekly Recap • De-referencing operator*
Objectives &
• Indirection operator->
T
Outlines
P
Operations
Ownership Issue
• Null Test operator! (operator== 0)
Pointers vs. • Comparison operator==, operator!=, ...
N
Reference
Smart Pointers
• Cast operator(int), operator(T*)
Policies • Address Of operator&
Storage Policy
Ownership Policy • Address Arithmetic operator+, operator-, operator++, operator--, operator+=,
Module Summary operator-=
• Indexing (array) operator[]
Module M56
L
Partha Pratim
Das
◦ Essential – Link (’next’) in a data structure
E
Weekly Recap
◦ Inessential – Apparent programming ease
Objectives &
T
Outlines . Passing Objects in functions: void MyFunc(MyClass *);
Raw Pointers . Smart expressions: while (p) cout << *p++;
P
Operations
Ownership Issue
Pointers vs.
• It is not a First Class Object (FCO) : An integer value is a FCO
N
Reference
• It Does not have a Value Semantics : Cannot COPY or ASSIGN at will
Smart Pointers
Policies • It is a Weak Semantics for Ownership of pointee
Storage Policy
Ownership Policy
Module Summary
Module M56
L
Partha Pratim
Das
E
Weekly Recap
Objectives &
T
Outlines
Raw Pointers
P
Operations
Ownership Issue
Pointers vs.
N
Reference
Smart Pointers
Policies
Storage Policy
Ownership Policy
Module Summary
Raw Pointers: Ownership Issue of Pointers
L
Partha Pratim
Das p = 0; // Lose ownership
Memory Leaks!
E
Weekly Recap
• Ownership Issue – COPY problem
Objectives &
MyClass *p = new MyClass; // Create ownership
T
Outlines
MyClass *q = p; // Copy ownership - no Copy Constructor! Performs shallow copy
Raw Pointers
delete q; // Delete Object & Remove ownership
P
Operations
delete p; // Delete Object - where is the ownership?
Ownership Issue
Pointers vs. Double Deletion Error!
N
Reference
• Solution Of these: Exception Handling through try-catch
Smart Pointers
void MyAction() {
Policies
Storage Policy
MyClass *p = 0;
Ownership Policy
try {
p = new MyClass;
Module Summary
p->Function();
}
catch (...) {
delete p; // Repeated code
throw;
}
delete p;
}
Programming in Modern C++ Partha Pratim Das M56.11
Pitfall: Handling Ownership Issue of Pointers using try-catch
Module M56
L
Partha Pratim
Das
E
Weekly Recap void MyDoubleAction() {
Objectives & MyClass *p = 0, *q = 0;
T
Outlines
try {
Raw Pointers p = new MyClass;
P
Operations
Ownership Issue
p->Function(); // May throw
Pointers vs. q = new MyClass;
N
Reference
q->Function(); // May throw
Smart Pointers
}
Policies
Storage Policy
catch (...) {
Ownership Policy delete p; // Repeated code
Module Summary delete q; // Repeated code
throw;
}
delete p;
delete q;
}
Module M56
So how do we deal with the objects to alleviate such problems?
L
Partha Pratim
Das
• The object itself – by value
E
Weekly Recap
◦ Performance Issue
Objectives &
◦ Redundancy Issue
T
Outlines
Raw Pointers
• As the memory address of the object – by pointer
P
Operations
Ownership Issue
Pointers vs.
◦ Lifetime Management Issue
N
Reference
◦ Code Prone to Memory Errors
Smart Pointers
Policies • With an alias to the object – by reference
Storage Policy
Ownership Policy ◦ Good when null-ness is not needed
Module Summary ◦ const-ness is often useful
Module M56
L
Partha Pratim
Das
E
Weekly Recap
Objectives &
T
Outlines
Raw Pointers
P
Operations
Ownership Issue
Pointers vs.
N
Reference
Smart Pointers
Policies
Storage Policy
Ownership Policy
Module Summary
Raw Pointers: Pointers vs. Reference
Module M56
L
Partha Pratim
Das
◦ Null reference is not needed
E
Weekly Recap
◦ Reference once created does not need to change
Objectives &
T
Outlines • Avoids
Raw Pointers
◦ The security problems implicit with pointers
P
Operations
Ownership Issue
Pointers vs.
◦ The (pain of) low level memory management (that is, delete)
N
Reference
• Without Pointer – Use Garbage Collection
Smart Pointers
Policies
Storage Policy
Ownership Policy
Module Summary
Module M56
L
Partha Pratim
Das
E
Weekly Recap
Objectives &
T
Outlines
Raw Pointers
P
Operations
Ownership Issue
Pointers vs.
N
Reference
Smart Pointers
Policies
Storage Policy
Ownership Policy Smart Pointers
Module Summary
Sources:
• The Rule of The Big Three (and a half) – Resource Management in C++, 2014
• What is a C++ unique pointer and how is it used? smart pointers part I, Sorush Khajepor, 2021
• What is a C++ shared pointer and how is it used? smart pointers part II, Sorush Khajepor, 2021
• What is a C++ weak pointer and where is it used? smart pointers part III, Sorush Khajepor, 2021
Module M56
L
Partha Pratim
Das
• Stores pointers to dynamically allocated (heap / free store) objects
E
Weekly Recap
Objectives &
• Improves raw pointers by implementing
T
Outlines
◦ Construction & Destruction
Raw Pointers
◦ Copying & Assignment
P
Operations
Ownership Issue
Pointers vs.
◦ Dereferencing:
N
Reference
. operator->
Smart Pointers
Policies . unary operator*
Storage Policy
Ownership Policy • Grossly mimics raw pointer syntax and semantics
Module Summary
Module M56
L
Partha Pratim
Das
• Lifetime Management
E
Weekly Recap
◦ Automatically deletes dynamically created objects at appropriate time
Objectives &
◦ On face of exceptions – ensures proper destruction of dynamically created objects
T
Outlines
Raw Pointers ◦ Keeps track of dynamically allocated objects shared by multiple owners
P
Operations
Ownership Issue • Concurrency Control
Pointers vs.
• Supports Idioms: RAII: Resource Acquisition is Initialization and RRID: Resource
N
Reference
Module M56
template <class T> // Pointee type T
class SmartPtr {
L
Partha Pratim
Das
public:
E
Weekly Recap // Constructible
Objectives &
// No implicit conversion from Raw ptr
T
Outlines explicit SmartPtr(T* pointee): // RAII
Raw Pointers pointee_(pointee) { }
P
Operations // Copy Constructible
Ownership Issue
SmartPtr(const SmartPtr& other);
Pointers vs.
N
Reference // Assignable
Smart Pointers SmartPtr& operator=(const SmartPtr& other);
Policies // Destroys the pointee
Storage Policy
Ownership Policy
~SmartPtr() { delete pointee_; } // RRID
// Dereferencing
Module Summary
T& operator*() const { ... return *pointee_; }
// Indirection
T* operator->() const { ... return pointee_; }
private:
T* pointee_; // Holding the pointee
};
Programming in Modern C++ Partha Pratim Das M56.19
Typical Smart Pointer Use: Mimic a Raw Pointer
Module M56
// A class for use
L
Partha Pratim
Das class MyClass {
public:
E
Weekly Recap
void Function();
Objectives &
// ...
T
Outlines
};
Raw Pointers
P
Operations
Ownership Issue // Create a smart pointer as an object
Pointers vs. SmartPtr<MyClass> sp(new MyClass); // RAII: sp takes ownership of the instance
N
Reference
Smart Pointers
Policies
// As if indirecting the raw pointer
Storage Policy sp->Function(); // (sp.operator->())->Function()
Ownership Policy
Module M56
L
Partha Pratim
Das
E
Weekly Recap
Objectives &
T
Outlines
Raw Pointers
P
Operations
Ownership Issue
Pointers vs.
N
Reference
Smart Pointers
Policies
Storage Policy
Ownership Policy
Module Summary
Smart Pointers: Policies
Module M56
L
Partha Pratim
Das
• It deletes the object once there are no more references to it
E
Weekly Recap
Objectives &
• Fast: Preferably zero de-referencing and minimal manipulation overhead
T
Outlines
Raw Pointers
• Raw pointers to be only explicitly converted into smart pointers. Easy search using grep
is needed (it is unsafe)
P
Operations
Ownership Issue
Pointers vs. • It can be used with existing code
N
Reference
Smart Pointers • Programs that do not do low-level stuff can be written exclusively using this pointer.
Policies
Storage Policy
No Raw pointers needed
Ownership Policy
• Thread-safe
Module Summary
• Exception safe
• It should not have problems with circular references
• Programmers would not keep raw pointers and smart pointers to the same object
Module M56
• The charter is managed through a set of policies that bring in flexibility and leads to
L
Partha Pratim
Das
different flavors of smart pointers
E
Weekly Recap
• Major policies include:
Objectives &
T
Outlines ◦ Storage Policy
Raw Pointers
◦ Ownership Policy
P
Operations
Ownership Issue ◦ Conversion Policy
Pointers vs.
◦ Null-test Policy
N
Reference
Smart Pointers
Policies
Storage Policy
Ownership Policy
Module Summary
Module M56
L
Partha Pratim
Das
E
Weekly Recap
Objectives &
T
Outlines
Raw Pointers
P
Operations
Ownership Issue
Pointers vs.
N
Reference
Smart Pointers
Policies
Storage Policy
Ownership Policy
Module Summary
Smart Pointers: Policies: Storage Policy
Module M56
L
Partha Pratim
Das
◦ The type of pointee: Specialized pointer types possible: FAR, NEAR
E
Weekly Recap
◦ By default, it is a raw pointer
Objectives &
◦ Other Smart Pointers possible: When layered
T
Outlines
Raw Pointers
• The Pointer Type (T*)
P
Operations
Ownership Issue
Pointers vs.
◦ The type returned by operator->
N
Reference
. Can be different from the storage type if proxy objects are used
Smart Pointers
Policies • The Reference Type (T&)
Storage Policy
Ownership Policy ◦ The type returned by operator*
Module Summary
Module M56
L
Partha Pratim
Das
E
Weekly Recap
Objectives &
T
Outlines
Raw Pointers
P
Operations
Ownership Issue
Pointers vs.
N
Reference
Smart Pointers
Policies
Storage Policy
Ownership Policy
Module Summary
Smart Pointers: Policies: Ownership Policy
Module M56
L
Partha Pratim
Das
• Exclusive Ownership
E
Weekly Recap
Objectives &
◦ Every smart pointer has an exclusive ownership of the pointee
T
Outlines ◦ std::unique ptr
Raw Pointers
◦ Use Destructive Copy
P
Operations
Ownership Issue
Pointers vs.
• Shared Ownership
N
Reference
◦ Ownership of the pointee is shared between Smart pointers – more than one smart
Smart Pointers
Policies pointer holds the same pointee
Storage Policy
Ownership Policy
◦ std::shared ptr
Module Summary ◦ std::weak ptr
◦ Track the Smart pointer references for lifetime
. Reference Counting
. Reference Linking
Module M56
L
Partha Pratim
Das
• Transfer ownership on copy
E
Weekly Recap
Objectives &
• Source Smart Pointer in a copy is set to NULL / nullptr
T
Outlines
Raw Pointers
• Available in C++ Standard Library
P
Operations ◦ std::unique ptr
Ownership Issue
Pointers vs.
• Implemented in
N
Reference
Module Summary
L
Partha Pratim
Das SmartPtr(SmartPtr& src) { // Src ptr is not const
pointee_ = src.pointee_; // Copy
E
Weekly Recap
src.pointee_ = 0; // Remove ownership for src ptr
Objectives &
}
T
Outlines
Raw Pointers
SmartPtr& operator=(SmartPtr& src) { // Src ptr is not const
if (this != &src) { // Check & skip self-copy
P
Operations
Ownership Issue delete pointee_; // Release destination object
Pointers vs.
pointee_ = src.pointee_; // Assignment
N
Reference
Smart Pointers
src.pointee_ = 0; // Remove ownership for src ptr
Policies }
Storage Policy return *this; // Return the assigned Smart Pointer
Ownership Policy
} // ...
Module Summary };
• Note that the copy operations (lvalue binding) here actually moves the resource – transfers
ownership. Hence, the source object needs a non-const reference
• Though the semantics is similar to move operations, these are different from move operators
(rvalue binding) due to lvalue binding
Programming in Modern C++ Partha Pratim Das M56.29
Ownership Policy: Destructive Copy: The Maelstrom Effect
Module M56
• Consider a call-by-value
L
Partha Pratim
Das
E
Weekly Recap void Display(SmartPtr<Something> sp); // passed by value - copy performed
Objectives & SmartPtr<Something> sp(new Something);
T
Outlines Display(sp); // sinks sp
Raw Pointers
P
Operations
Ownership Issue • Display acts like a maelstrom of smart pointers:
Pointers vs.
◦ It sinks any smart pointer passed to it
N
Reference
Smart Pointers
Policies
◦ After Display(sp) is called, sp holds the null pointer
Storage Policy
Ownership Policy
• Lesson: Pass Smart Pointers by Reference
Module Summary • Smart pointers with destructive copy cannot usually be stored in containers and in
general must be handled with care
• STL Containers need FCO
Module M56
L
Partha Pratim
Das
• Good at enforcing ownership transfer semantics
E
Weekly Recap
Objectives &
◦ Use the maelstrom effect to ensure that the function takes over the passed-in
T
Outlines pointer
Raw Pointers
• Good as return values from functions
P
Operations
Ownership Issue
Pointers vs. ◦ The pointee object gets destroyed if the caller does not use the return value
N
Reference
Smart Pointers • Excellent as stack variables in functions that have multiple return paths
Policies
Storage Policy
• Available in Standard Library
Ownership Policy
◦ std::auto ptr [C++03, deprecated in C++11, removed in C++17]
Module Summary
◦ std::unique ptr [C++11]
L
Partha Pratim
Das • Reference Counting: A count of the number of Smart pointers (references) to a pointee
◦ Non-Intrusive Counter: Multiple / Single Raw Pointers per pointee with count in free store
E
Weekly Recap
T
Outlines
◦ Destroy the pointee Object when the count equals 0
Raw Pointers
• Reference Linking: All Smart pointers to a pointee are linked on a chain
P
Operations
Ownership Issue
Pointers vs. ◦ The exact count is not maintained – only check if the chain is null
N
Reference
◦ Destroy the pointee Object when the chain gets empty
Smart Pointers
Policies • Available in C++ Standard Library
Storage Policy
Ownership Policy
◦ std::shared ptr
Module Summary ◦ std::weak ptr
• Implemented in
◦ Constructor
◦ Copy Constructor
◦ operator=
◦ Destructor
Programming in Modern C++ Partha Pratim Das M56.32
Ownership Policy: Exclusive and Shared
L
Partha Pratim
Das
E
Weekly Recap
Objectives &
T
Outlines
Raw Pointers
P
Operations
Ownership Issue
Pointers vs.
N
Reference
Smart Pointers
Policies
Storage Policy
Ownership Policy • Exclusive Ownership Policy • Shared Ownership Policy
Module Summary • Transfer ownership on copy • Multiple Smart pointers to same pointee
• On Copy: Source is set to NULL • On Copy: Reference Count (RC) incremented
• On Delete: Destroy the pointee Object • On Delete: RC decremented, if RC > 0.
Pointee object destroyed for RC = 0
• std::auto ptr (C++03), std::unique ptr • std::shared ptr, std::weak ptr (C++11)
(C++11)
• Coded in: C-Ctor, operator= • Coded in: Ctor, C-Ctor, operator=, Dtor
Programming in Modern C++ Partha Pratim Das M56.33
Ownership Policy: Exclusive and Shared
Module M56
L
Partha Pratim
Das
E
Weekly Recap
Objectives &
T
Outlines
Extra indirection & non-intrusive counter
Raw Pointers
P
Operations
Ownership Issue
Pointers vs.
N
Reference
Module M56
• Revisited Raw Pointers and discussed how to deal with the objects through raw pointer
L
Partha Pratim
Das
• Introduced Smart pointers with typical interface and use
E
Weekly Recap
Objectives &
• Introduced some of the policies for smart pointer:
T
Outlines
◦ Storage Policies
Raw Pointers
◦ Ownership Policies
P
Operations
Ownership Issue
Pointers vs.
N
Reference
Smart Pointers
Policies
Storage Policy
Ownership Policy
Module Summary