Developed By Ms. K.M.Sanghavi
Pointers
Memory Management : Dynamic Pointers
Linked List Example
Smart Pointers
•Auto Pointer
•Unique Pointer
• Shared Pointer
•Weak Pointer
Memory Management
• In order to create an array in C/C++ you have to know its size in advance during compile time, in other words it has to be a constant
int size;
cout << ”Enter size of array : ”;
cin >> size;
int array[size]; // ERROR size has to be a constant
• Solution in C++, use vector class from the STL which is expandable
Memory Management Date* void CreateDate() // allows the user to create a date object
{
int day, month, year;
char dummy;
cout << ”Enter dd/mm/yyyy :”;
cin >> day >> dummy >> month >> dummy >> year;
Date date(day, month, year);
return &date; // ERROR!! Scope of date ends with end of function
}
Date *ptr;
ptr=CreateDate(); // call CreateDate() to generate a new date
cout << ”You entered ” << *ptr << endl;
// variable to which ptr points no longer exist , segmentation fault !!!
Memory Management • The new operator in C++ can be used to create objects that can be used
after returning from a function
• Objects allocated in dynamic memory are called heap objects or to be ”on free store” and have a permament existence
Date* CreateDate() // allows the user to create a date object
{
int day, month, year;
char dummy;
cout << ”Enter dd/mm/yyyy :”;
cin >> day >> dummy >> month >> dummy >> year;
Date *tmpptr = new Date date(day, month, year);
return tmpptr; // returns pointer to heap object
}
Date *ptr;
ptr=CreateDate(); // call CreateDate() to generate a new date
cout << ”You entered ” << *ptr << endl; // ok, ptr refers to heap object
Memory Management • New can also be used to allocate blocks of memory
• The delete operator is used to release the memory allocated with new once it is no longer needed
#include <cstring>
char *str =”This is an old C-style string”;
int len=strlen(str); // computes the length of str
char *ptr; // create a pointer to char
ptr = new char[len+1]; // set aside memory string + ’\0’
strcpy(ptr,str); // copy str to new memory
cout << ”ptr=” << ptr << endl;
delete [] ptr; // release ptr’s memory
Linked List Example struct link // one element of list
{
int data; // data item
link *next; // pointer to next element
};
class linklist
{
private:
link* first; // pointer to first link
public:
linklist() { first = NULL;} // no argument constructor
void additem(int d); // add data item (one link)
void display(); // display all links
}
Linked List Example void linklist::additem(int d) // add data item
{
link* newlink = new link; // create a new link
newlink->data = d; // give it data d
newlink->next=first; // it points to the next link
first = newlink; // now first points to this link
}
void linklist::display() // display all links
{
link* current=first; // set ptr to first link
while(current != NULL) // until ptr points beyond last link
{
cout << current->data << ” ”; // print data
current=current->next; // move to next link
}
}
Smart Pointers • Consider the following simple C++ code with
normal pointers.
MyClass *ptr = new MyClass();
ptr->doSomething();
// We must do delete(ptr) to avoid memory leak
• Using smart pointers, we can make pointers to work in way that we don’t need to explicitly call delete.
Smart Pointers • Smart pointer is a wrapper class over a pointer
with operator like * and -> overloaded.
• The objects of smart pointer class look like pointer, but can do many things that a normal pointer can’t like automatic destruction reference counting and more.
• The idea is to make a class with a pointer, destructor and overloaded operators like * and ->.
Smart Pointers • Since destructor is automatically called when
an object goes out of scope, the dynamically allocated memory would automatically deleted (or reference count can be decremented).
Example for Smart Pointers #include<iostream> using namespace std; class SmartPtr { int *ptr; // Actual pointer public: // Constructor explicit SmartPtr(int *p = NULL) { ptr = p; }
Example for Smart Pointers // Destructor ~SmartPtr() { delete(ptr); } // Overloading dereferencing operator int &operator *() { return *ptr; } int *operator ->() //Overloading Access operator { return ptr; } };
Example for Smart Pointers int main() { SmartPtr ptr(new int()); *ptr = 20; cout << *ptr; // We don't need to call delete ptr: when the object // ptr goes out of scope, destructor for it is automatically // called and destructor does delete ptr. return 0; }
Use of Smart Pointers
• Automatic cleanup.
• Automatic initialization
• Ownership transfer
• Reference counting
• To shorten allocation and deallocation time.
• Since C++ does not provide automatic garbage collection like some other languages, smart pointers can be used for that purpose.
Smart Pointers
• We can make Smart pointers to work on all types. For this we need to use Templates (covered in next unit)
• C++ libraries provide implementations of smart pointers in the form of – auto_ptr : deprecated
– unique_ptr : Same as auto_ptr
– shared_ptr and
– weak_ptr
• All these pointers exist in <memory> header file
Unique Pointers • unique_ptr is a container for a raw pointer,
which the unique_ptr is said to own.
• A unique_ptr explicitly prevents copying of its contained pointer (as would happen with normal assignment),
• But the std::move function can be used to transfer ownership of the contained pointer to another unique_ptr.
• A unique_ptr cannot be copied because its copy constructor and assignment operators are explicitly deleted.
Unique Pointers
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 rendered invalid.
p3.reset(); //Deletes the memory.
p1.reset(); //Does nothing.
Shared Pointers
• 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 shared_ptr.
• An object referenced by the contained raw pointer will be destroyed when and only when all copies of the shared_ptr have been destroyed.
Shared Pointers
std::shared_ptr<int> p1(new int(5));
std::shared_ptr<int> p2 = p1; //Both now own the memory.
p1.reset(); //Memory still exists, due to p2.
p2.reset(); //Deletes the memory, since no one else owns the memory.