COMP6771 Advanced C++ Programming

Similar documents
Pointers. Developed By Ms. K.M.Sanghavi

COMP6771 Advanced C++ Programming

COMP6771 Advanced C++ Programming

COMP6771 Advanced C++ Programming

Memory Leak. C++: Memory Problems. Memory Leak. Memory Leak. Pointer Ownership. Memory Leak

Homework 4. Any questions?

CSE 333 Lecture smart pointers

CSE 333 Lecture smart pointers

The issues. Programming in C++ Common storage modes. Static storage in C++ Session 8 Memory Management

Short Notes of CS201

Object-Oriented Programming for Scientific Computing

CS201 - Introduction to Programming Glossary By

Smart Pointers. Some slides from Internet

COMP6771 Advanced C++ Programming

ALL ABOUT POINTERS C/C++ POINTERS

Vector and Free Store (Pointers and Memory Allocation)

Outline. 1 Function calls and parameter passing. 2 Pointers, arrays, and references. 5 Declarations, scope, and lifetimes 6 I/O

Modern C++ for Computer Vision and Image Processing. Igor Bogoslavskyi

Chapter 17 vector and Free Store

COMP 2355 Introduction to Systems Programming

Assertions and Exceptions

RAII and Smart Pointers. Ali Malik

Laboratorio di Tecnologie dell'informazione. Ing. Marco Bertini

Chapter 17 vector and Free Store. Bjarne Stroustrup

2 ADT Programming User-defined abstract data types

Chapter 17 vector and Free Store

Object-Oriented Programming for Scientific Computing

Smart Pointers in C++11

C++ Smart Pointers. CSE 333 Autumn 2018

COMP6771 Advanced C++ Programming

Modern and Lucid C++ Advanced for Professional Programmers. Part 3 Move Semantics. Department I - C Plus Plus Advanced

CPSC 427: Object-Oriented Programming

CMSC 330: Organization of Programming Languages. Ownership, References, and Lifetimes in Rust

Exception Namespaces C Interoperability Templates. More C++ David Chisnall. March 17, 2011

Pointers! Arizona State University 1

Object Oriented Software Design II

INITIALISING POINTER VARIABLES; DYNAMIC VARIABLES; OPERATIONS ON POINTERS

Chapter 13: Copy Control. Overview. Overview. Overview

CSCI-1200 Data Structures Fall 2011 Lecture 24 Garbage Collection & Smart Pointers

Midterm Review. PIC 10B Spring 2018

CS24 Week 3 Lecture 1

vector and Free Store

CMSC 202 Section 010x Spring Justin Martineau, Tuesday 11:30am

CSE 333. Lecture 11 - constructor insanity. Hal Perkins Paul G. Allen School of Computer Science & Engineering University of Washington

C++ Programming Lecture 4 Software Engineering Group

05-01 Discussion Notes

6 Architecture of C++ programs

Project. C++: Smart Pointers. The Plan. Announcement. Memory Leak. Pointer Ownership. Today: STL 1 Wednesday: STL 2 Thursday: Smart Pointers

04-17 Discussion Notes

G52CPP C++ Programming Lecture 13

COMP6771 Advanced C++ Programming

Copy Control 2008/04/08. Programming Research Laboratory Seoul National University

Exception Safety. CS 311 Data Structures and Algorithms Lecture Slides Wednesday, October 28, Glenn G. Chappell. continued

Operating Systems CMPSCI 377, Lec 2 Intro to C/C++ Prashant Shenoy University of Massachusetts Amherst

Smart Pointers - What, Why, Which?

04-19 Discussion Notes

CSCI-1200 Data Structures Spring 2017 Lecture 27 Garbage Collection & Smart Pointers

C++ Programming Lecture 7 Software Engineering Group

Exception Safe Coding

Part VII. Object-Oriented Programming. Philip Blakely (LSC) C++ Introduction 194 / 370

Intermediate Programming, Spring 2017*

Objects Managing a Resource

Pointers and Dynamic Memory Allocation

CSC 211 Intermediate Programming. Arrays & Pointers

Advanced C++ 4/13/2017. The user. Types of users. Const correctness. Const declaration. This pointer and const.

A brief introduction to C++

Fast Introduction to Object Oriented Programming and C++

G52CPP C++ Programming Lecture 16

Abstract. Vector. Overview. Building from the ground up. Building from the ground up 1/8/10. Chapter 17 vector and Free Store

C11: Garbage Collection and Constructors

GEA 2017, Week 4. February 21, 2017

CS201 Some Important Definitions

Lecture 15a Persistent Memory & Shared Pointers

Arrays. Returning arrays Pointers Dynamic arrays Smart pointers Vectors

19. Classes. Encapsulation: public / private. Member Functions: Declaration. Member Functions: Call. class rational { int n; int d; // INV: d!

A Crash Course in (Some of) Modern C++

Consider the program...

CS

See the CS 2704 notes on C++ Class Basics for more details and examples. Data Structures & OO Development I

Interview Questions of C++

Vector and Free Store (Vectors and Arrays)

PHY4321 Summary Notes

Introducing C++ to Java Programmers

Lecture 9. Pointer, linked node, linked list TDDD86: DALP. Content. Contents Pointer and linked node. 1.1 Introduction. 1.

17. Classes. Encapsulation: public / private. Member Functions: Declaration. Member Functions: Call. class rational { int n; int d; // INV: d!

A class is a user-defined type. It is composed of built-in types, other user-defined types and

CSE 374 Programming Concepts & Tools. Hal Perkins Spring 2010

21. Dynamic Datatypes and Memory Management

Pointers and References

CMSC 330: Organization of Programming Languages. Memory Management and Garbage Collection

Part X. Advanced C ++

CPSC 427: Object-Oriented Programming

CMSC 330: Organization of Programming Languages

Pointers and Memory 1

The vector Class and Memory Management Chapter 17. Bjarne Stroustrup Lawrence "Pete" Petersen Walter Daugherity Fall 2007

Acknowledgements These slides are based on Kathryn McKinley s slides on garbage collection as well as E Christopher Lewis s slides

COMP6771 Advanced C++ Programming

Class Destructors constant member functions

ECE 449 OOP and Computer Simulation Lecture 14 Final Exam Review

CPSC 427: Object-Oriented Programming

Transcription:

1.. COMP6771 Advanced C++ Programming Week 5 Part Two: Dynamic Memory Management 2016 www.cse.unsw.edu.au/ cs6771

2.. Revisited 1 #include <iostream> 2 3 struct X { 4 X() { std::cout << "X() "; } 5 }; 6 7 struct Y { 8 Y() { std::cout << "Y() "; } 9 }; 10 11 class A { 12 X x; 13 public: 14 A() { std::cout << "A() "; } 15 }; 16 17 class B : public A { 18 Y y; 19 public: 20 B() { std::cout << "B() "; } 21 }; 22 23 int main() { 24 B b; 25 } What is the output? a. X() A() Y() B() b. A() X() B() Y() c. Y() B() X() A() d. B() Y() A() X() e. X() Y() A() B()

3.. Revisited 1 #include <iostream> 2 3 struct X { 4 X() { std::cout << "X() "; } 5 }; 6 7 struct Y { 8 Y() { std::cout << "Y() "; } 9 }; 10 11 class A { 12 X x; 13 public: 14 A() { std::cout << "A() "; } 15 }; 16 17 class B : public A { 18 Y y; 19 public: 20 B() { std::cout << "B() "; } 21 }; 22 23 int main() { 24 B b; 25 } What is the output? a. X() A() Y() B() b. A() X() B() Y() c. Y() B() X() A() d. B() Y() A() X() e. X() Y() A() B()

4.. Finalisation Revisited 1 #include <iostream> 2 3 struct X { 4 X() { std::cout << " X() "; } 5 }; 6 7 struct Y { 8 Y() { std::cout << " Y() "; } 9 }; 10 11 class A { 12 X x; 13 public: 14 A() { std::cout << " A() "; } 15 }; 16 17 class B : public A { 18 Y y; 19 public: 20 B() { std::cout << " B() "; } 21 }; 22 23 int main() { 24 B b; 25 } What is the output?

5.. Finalisation Revisited 1 #include <iostream> 2 3 struct X { 4 X() { std::cout << " X() "; } 5 }; 6 7 struct Y { 8 Y() { std::cout << " Y() "; } 9 }; 10 11 class A { 12 X x; 13 public: 14 A() { std::cout << " A() "; } 15 }; 16 17 class B : public A { 18 Y y; 19 public: 20 B() { std::cout << " B() "; } 21 }; 22 23 int main() { 24 B b; 25 } What is the output? Reversed: B() Y() A() X()

6.. and Named/Unnamed Objects Lifetime: the period of time in which memory is allocated for an object Different kinds of objects: Static objects: allocated in a global (static) area Local (or automatic or stack) objects Heap objects Named objects: (named by the programmer): their lifetimes determined by their scope Heap objects (unnamed objects): their lifetimes determined by the programmer

7.. Local Objects void f() { int i = 1; } // automatic Lifetime: created when f is called and cease to exist when this invocation of f completes (with destructors called) Primitive objects are not initialised by default Class objects are initialised by constructors The same name denotes different objects during different invocations of the function f Memory management done by the compiler

.. Local Objects (Cont d) 1 { 2 std::stack<int> s1; 3 { 4 std::stack<int> s2; 5 } ---> call stack() for s2 6 } ---> call stack() for s1 Every object inaccessible at its closing } s The destructors s1 and s2 are called when s1 and s2 die 1 { 2 std::stack<int> s1; 3 { 4 std::stack<int> &s2 = s1; 5 } --->??? 6 } ---> call stack() for s1 8 s2 is a reference to s1 The destructor for s1 is called when s1 dies

9.. Temporary Objects Unnamed objects created on the stack by the compiler. Read the detailed rules: http://www-01.ibm.com/support/ knowledgecenter/ssgh3r_8.0.0/com.ibm.xlcpp8a.doc/ language/ref/cplr382.htm%23cplr382 Used during reference initialization and during evaluation of expressions including type conversions, argument passing, function returns, and evaluation of the throw expression. There are two exceptions in the destruction of full-expressions: The expression appears as an initializer for a declaration defining an object: the temporary object is destroyed when the initialization is complete. A reference is bound to a temporary object: the temporary object is destroyed at the end of the reference s lifetime.

10.. of Temporary Objects 1 #include<vector> 2 3 std::vector<int> f() { return std::vector<int>{}; } 4 5 void g() { 6 const std::vector<int>& v = f(); 7 } The lifetime of the temporary vector created f may persist as long as the reference is live.

11.. Static Objects Four categories of objects: Local static objects Global objects Namespace objects Class static objects Memory management done by the compiler These objects are often referred to as global/static objects.

12.. (Local) Static Objects int f() { static int i = 0; return ++i; } cout << f(); // prints 1 cout << f(); // prints 2 lifetime: created when f is first called and persist until the program completes (with destructors called) Primitive objects are initialised to default values Class objects are initialised by constructors (Local) static objects are still visible locally

13.. Global, Namespace and Class Static Objects file.cpp: std::stack<int> s; // global namespace X { std::queue<short> q; // namespace } class Y { static std::list<char> l; // class static } All created at program start-up and persist until the program completes (with their destructors called) Primitive objects initialised to default values Class objects are initialised by constructors

14.. Heap (or Free-Store) Objects Allocated via new and persist until deleted via delete In int pi = new int{1}, two objects are involved: pi named new int{1} 1 unnamed important pi is destroyed at the end of its lifetime automatically the pointed-to object must be destroyed explicitly Thus, important to remember: delete pi delete *pi unnamed delete pi delete named.1 First, the destructor for the pointed-to object, *p, is called.2 Then, the corresponding memory is freed. Ṭhe destructor for a built-in type does nothing.

15.. Heap Objects (Cont d) int* f() { int *pi = new int{1}; return pi; } int main() { int *pj = f(); delete pj; } pi and pj are named local objects new int(1) is an unnamed heap object

16.. Match delete with the Corresponding new int *pi = new int{1}; int *pj = new int[10]; // an array of 10 ints uninitialised... delete pi; // delete [] pi is undefined delete [] pj; // delete pj is undefined An array object typically contains the information regarding the number of its elements

17.. new: Dynamically Allocate and Initialise Objects 1 int *pi = new int; // an uninitialised int 2 int *pj = new int{}; // an int initialised to 0 3 4 std::string *ps1 = new std::string; // initialised to empty 5 // string by calling string s default ctor 6 std::string *ps2 = new std::string{"abc"}; // initialised to 7 // string "abc" 8 9 auto *pf = new auto{3.14}; 10 // inferred as float *pf = new float{3.14}; 11 12 const int *pci = new const int{100}; 13 // an const int object initialised to 100 14 15 std::vector<int> *pv1 = new std::vector<int>{}; 16 // a vector<int> initialised to be empty 17 // if allocation fails, throws std::bad_alloc 18 19 std::vector<int> *pv2 = new (nothrow) std::vector<int>{}; 20 // a vector<int> initialised to be empty 21 // if allocation fails, returns nullptr

18.. Many Memory-Corruption Bugs in C/C++ Code! 1 int i, *pi1 = &i, *pi2 = nullptr; 2 double *pd = new double{3.14}, *pd2 = pd; 3 4 delete i; // error: i is not a pointer 5 delete pi1; // undefined: pi1 points to a stack location 6 delete pd; // ok 7 delete pd2; // double free! 8 *pd = 1.0; // accessing a a dangling pointer 9 delete pi2; // ok: deleting nullptr does nothing 10 11 int* foo() { 12 *pi = new std::vector<int>{50}; 13 return pi; 14 } 15 16 int *pj = foo(); 17 // If the programmer never calls delete pj, then you have 18 // a memory leak! The memory storing the vector has leaked.

19.. Resetting the Value of a Pointer After a delete A deleted pointer is not automatically nullified Set a deleted pointer to nullptr yourself: 1 int *p = new int{1}; 2 delete p; 3 p = nullptr; We nullify the pointers in a moved-from object: 1 UB_stack::UB_stack(const UB_stack &&s) { 2 head_ = s.head_; 3 s.head = nullptr; // put the moved-from object 4 } // in a valid state to be destroyed

20.. new: Dynamic Arrays Allocate and initialise dynamic arrays 1 int *p = new int[5]; // block of 5 uninitialised ints 2 int *p = new int[5]{}; // block of 5 ints initialised to 0 3 4 // block of 5 empty strings 5 std::string *p = new std::string[5]; 6 // block of 5 empty strings 7 std::string *p = new std::string[5]{}; 8 9 int *p = new int[5](1); // error 10 std::string *p = new std::string[5]("abc"); // error 11 12 int *p = new int[5]{0, 2, 3, 4, 5}; // ok 13 std::string *p = new std::string[5]{"an"}; 14 // ok: the first initialised 15 // to "an" and the last four to empty strings

21... Motivations for Memory Management Standard solution (value semantics) SMatrix operator+(const SMatrix &a, const SMatrix &b) { SMatrix c = a; return c+=b; } // can be efficient now in C++11 due to move ctor/assignment Efficient SMatrix& operator+(const SMatrix &a, const SMatrix &b) { SMatrix c = a; return c+=b; } // but incorrect Efficient SMatrix& operator+(const SMatrix &a, const SMatrix &b) { SMatrix *c = new SMatrix; return *c+=b; } // but who is to free the heap-allocated object? When objects are large, heap objects may be used. Using pointers is a burden on users = memory management techniques (smart pointers, reference counting, handles, etc.) so that users don t have to manage pointers explicitly themselves

22.. Smart Pointers: Motivations Memory leak: void f() { X* x = new X{};... delete x; } if x is not deleted, you suffer the memory leak problem If an exception is thrown in, delete x will not be executed. You will then suffer the memory leak problem Double free and dangling pointers

23.. One Solution: Bad Programming Style void f() { X* x = new X{}; try {... } catch (...) { delete x; throw; // rethrow the exception } } delete x;

24.. Smart Pointers: Overloading of > Usual notations: if p is a built-in pointer, p->x accesses the member x if p is an object or a reference to an object, p.x accesses the member x Smart pointers: a class type exhibits a pointer-like behaviour when the -> is overloaded If p is an object or reference, p->x can be used p is known as a smart pointer Item 28, Meyers More Effective C++

25.. Basic Idea: Defining a Smart Pointer to Strings 1 #include <iostream> 2 3 class StringPtr { 4 public: 5 StringPtr(std::string *p) : ptr{p} { } 6 StringPtr() { delete ptr; } 7 std::string* operator->() { return ptr; } 8 std::string& operator*() { return *ptr; } 9 private: 10 std::string *ptr; 11 }; 12 13 int main() { 14 std::string *ps = new std::string{"smart pointer"}; 15 StringPtr p{ps}; 16 std::cout << *p << std::endl; 17 std::cout << p->size() << std::endl; 18 }

26.. Using (Named) Objects to Prevent Memory Leaks Place a pointer inside a named object and have the object manage the pointer for you class StringPtr { ~StringPtr() { delete ptr; }... std::string *ptr; }; User code: { StringPtr p(new std::string("smart pointer")); } <-- *ptr freed here when ~StringPtr() called The object p s destructor will delete the heap string object

27.. What About Double Free? Yes, it is still with us: class StringPtr { ~StringPtr() { delete ptr; }... std::string *ptr; }; User code: { StringPtr p(new std::string("smart pointer")); { StringPtr q(p); } <-- *ptr freed here std::cout << p->size() // Oops } <-- *ptr freed again

28.. Reference Counting (RC) A classic automatic garbage collection technique Can be used manually by the C++ programmer to prevent memory leaks, and the dangling pointer problem FAQs 31.10 31.11: RC with copy-on-write semantics Item 29, Meyers More Effective C++

29.. A Simple RC Scheme (without COW) 1 class PointPtr; 2 3 class Point { 4 public: 5 friend class PointPtr; 6 static PointPtr create(); 7 static PointPtr create(int i, int j); 8 private: 9 Point() : count_(0) { i = j = 0; } 10 Point(int i, int j) : count_(0) { 11 this->i = i; this->j = j; 12 } 13 unsigned count_; 14 int i, j; 15 }; Users cannot construct point objects directly Factory methods used to construct point objects

30... A Simple RC Scheme (Cont d) 1 class PointPtr { // smart pointer 2 public: 3 Point* operator-> () { return p_; } 4 Point& operator* () { return *p_; } 5 PointPtr(Point* p) : p_{p} { ++p_->count_; } // p cannot be NULL 6 PointPtr() { if (--p_->count_ == 0) delete p_; } 7 PointPtr(const PointPtr& p) : p_{p.p_} { ++p_->count_; } 8 PointPtr& operator= (const PointPtr& p) { 9 ++p.p_->count_; 10 if (--p_->count_ == 0) delete p_; 11 p_ = p.p_; 12 return *this; 13 } 14 private: 15 Point* p_; // p_ is never NULL 16 }; 17 inline PointPtr Point::create() { return new Point(); } 18 inline PointPtr Point::create(int i, int j) { 19 return new Point(i,j); 20 }

31.. A Simple RC Scheme (Cont d) Client code: int main() { PointPtr p1 = Point::create(1, 1); PointPtr p2 = p1; p1 = Point::create(2, 2); p2 = p1; } In the two overloaded Point::create, the constructor PointPtr (Point *p) is called on return

.. Does new Do More Than Allocate Memory (FAQ12.01)? Consider: 1 X *p = new X(); The compiler-generated code looks something like: 1 X *p = (X*) operator new( sizeof(x) ); //Step 1 2 try { 3 new (p) X(); // Step 2 4 } catch (...) { 5 operator delete(p); 6 throw; 7 } No memory leak occurs if the constructor throws an exception 32

.. Does delete Do More Than Deallocate Memory (FAQ12.01)? Consider: 1 delete p // p is an object of class X The compiler-generated code looks something like: 1 p-> X(); //Step 1: calling the destructor 2 operator delete(p); //Step 2: freeing the memory Deleting a null pointer is safe 1 if (p!= 0) delete p; // test redundant 2 // the test done in operator delete(void *p) 33

34.. A Variety of Smarter Pointers! Smart pointers: Strategies for handling p = q, where p and q are smarter pointers New smart pointers introduced in C++11: unique ptr shared ptr weak ptr Why smarter pointers? Less bugs (e.g., fewer double-free & dangling pointer problems) Exception safety (e.g., automatic memory deallocation) Gabagge collection (RC) Efficiency (copy-on-write)

35.. unique ptr ( 12.1.5) A unique ptr owns the object to which it points to The underlying object always owned by one owner only When the unique ptr goes out of scope, its internal object pointed to by its internal pointer is destroyed ptr 1 { 2 // C++14: auto p = std::make_unique<ub_stack>(); 3 std::unique_ptr<ub_stack> p(new UB_stack{}); 4 p.get()->push(1); 5 p.get()->push(2); 6 } unique_ptr<ub_stack> { delete ptr; } head 2 1 next next nullptr Explicit ownership transfer: 1 std::unique_ptr<ub_stack> p(new UB_stack{}); 2 std::unique_ptr<ub_stack> q1 = p; // error: no copy 3 std::unique_ptr<ub_stack> q2; 4 q2 = p; // error: no assignment 5 std::unique_ptr<ub_stack> q3; 6 q3.reset(p.release()); // ok: ownership transfer

36.. Passing and Returning unique ptr 1 std::unique_ptr<ub_stack> foo() { 2 std::unique_ptr<ub_stack> p(new UB_stack{}); 3 p.get().push(1); 4 p.get().push(2); 5 return p; 6 } 7 8 int main() { 9 std::unique_ptr<ub_stack> q = foo(); 10 } Can assign/copy a temporary unique ptr that is about to die The compiler makes sure that q will be the unique owner after the call to foo returned; the temporary has lost the ownership

37.. Smarter Pointers and Exception Smarter pointers: 1 void f() { 2 std::unique_ptr<ub_stack> up(new UB_stack{});; 3 4 code that throws an exception 5 6 } // the destructor for up called here 7 // the underlying stack object is freed Dumb pointers: 1 void f() { 2 UB_stack *p = new UB_stack(); 3 4 code that throws an exception 5 6 delete p; 7 } // the destructor for *p not called here 8 // the underlying stack object has leaked. Ṭhe destructors for all named objects are called only!

38.. unique ptr 1 std::unique_ptr<int> x = new int{i}; 2 std::unique_ptr<int> y = x; // Compile error 3 std::unique_ptr<int> z = std::move(x); // Transfers ownership 4 // z now owns the memory 5 // x is rendered invalid 6 z.reset(); // Deletes the memory copy constructor and assignment disabled move used to transfer ownership Create more than one owner (Don t do this!): { int *pi = new int{1}; std::unique_ptr<int> p ( pi ); std::unique_ptr<int> q ( pi ); } --> new int(1) will be deleted twice Two unique ptr objects should not hold ownership to the same heap object. The double-free problem!

39.. shared ptr ( 12.1.1) Allows multiple pointers to point to the same object (with the number of pointers reference-counted) The pointed-to object is destroyed when the last pointer goes out of scope 1 { 2 auto p = std::make_shared<ub_stack>(); 3 p.get()->push(1); 4 p.get()->push(2); 5 { 6 std::shared_ptr<ub_stack> q = p; 7 } ptr rc ptr rc 8 // shared_ptr() called here: ref count (rc) = 1 9 10 } // shared_ptr() called here: ref count (rc) = 0 11 // the stack and counter destroyed The destructor: head 2 1 2 next next 1 shared_ptr::shared_ptr() { 2 if (--*ref count == 0) { delete ptr; delete ref count; } 3 } nullptr

40.. shared ptr std::shared_ptr<int> x = std::make_shared<int>(1); std::shared_ptr<int> y = x; // Both now own the memory x.reset(); // Memory still exists, due to y. y.reset(); // Deletes the memory, since // no one else owns the memory Referece counted ownership: every copy of the same shared ptr owns the same pointed-to object Freed only when all instances are destroyed What about cycles? (e.g., A has shared ptr to B, B has shared ptr to A)

41.. weak ptr 1 std::shared_ptr<int> x = std::make_shared<int>(1); 2 std::weak_ptr<int> wp = x; // x owns the memory 3 { 4 std::shared_ptr<int> y = wp.lock(); // x and y own the memory 5 if (y) 6 { // Do something with y } 7 } // y is destroyed. Memory is owned by x 8 9 x.reset(); // Memory is deleted 10 11 std::shared_ptr<int> z = wp.lock(); // Memory gone; get null ptr 12 if (z) 13 { // will not execute this } Useful when you need to access to a resource through a pointer that can outlive the resource Read: http://www.drdobbs.com/weak-pointers/184402026

42.. weak ptr + shared ptr ( 12.1.6) Points to an object managed by a shared ptr Doesn t get reference-counted 1 { 2 auto p = std::make_shared<ub_stack>(); 3 p.get()->push(1); p ptr 4 p.get()->push(2); rc 5 std::weak_ptr<ub_stack> wp = p; 6 7 { 8 9 std::shared_ptr<ub_stack> q = p; 10 11 // The snapshot at this point 12 } // shared_ptr(): rc = 1 13 wp ptr rc 14 p.reset(); // shared_ptr(): rc = 0 15 // the stack destroyed 16 } // weak_ptr(): weak-rc = 0 q ptr rc head 2 1 2 1 next next rc weak-rc Conceptually illustrated but may vary across implementations nullptr

43.. Smart Pointers for Arrays Different operations provided for arrays ( 12.2.1) 1 #include<iostream> 2 #include<memory> 3 #include "UB_stack.h" 4 5 int main() { 6 auto p =std::unique_ptr<ub_stack[]>(5); 7 p[0].push(1); 8 p[1].push(2); 9 } // <-- delete[] called on the underlying array object shared ptr does not provide support for arrays. You can supply your own deleter (Page 480) - Do not do this!: 1 struct deleter { 2 void operator ()( UB_stack const * p) { delete[] p; } 3 }; 4 5 int main() { 6 std::shared_ptr<ub_stack> p (new UB_stack[5](), deleter()); 7 }

44.. Reading Section 18.1 C++ Memory and Resource Management http://www.informit.com/articles/article.asp?p=30642 C++ FAQ Lite: http://yosefk.com/c++fqa/exceptions.html How is exception handling implemented? http://www.codeproject.com/cpp/exceptionhandler.asp