Dynamic Memory And Smart Pointers(I)
In c++,we have static memory for local static objects and class static data members and for variables defined outside any functions(global variables),and stack memory for nonstatic objects defined inside functions.Objects allocated in static or stack memory will be automatically created and destroyed by the compiler.In addition to static or static memory,we can use the heap for objects that can be dynamically allocated at the run time.The program controls the life time of dynamic objects,our code must explictly destroy such objects when they are no longer needed.
1.introduction
In c++,dynamic memory is managed through new
and delete
to allocate and destroy.However, memory is problematic because it’s quite complex to know when to destroy the object or you even forget these things.So, the the new library provided two smart pointer types that manage dynamic objects:
- shared_ptr: which allow multiple pointers to refer to the same object.
- unique_ptr: which owns the objects which it points.
There is also a pointer named weak_ptr that is a weak reference to an object managed by a shared_ptr.
All three pointers are defined in memory
header.
2.The shared_ptr Class
Operations common to shared_ptr
and unique_ptr
shared_ptr<T> sp //Null smart pointer that can point to objects of T
unique_ptr<T> up
p //use p as a condition:true if p points to an object
*p //dereference to get the object to which p points
p->mem //same as (*p).mem
p->get() //return the pointer in p
swap(p,q);
Operations Specific to shared_ptr
make_shared<T>(arg) //return a shared_ptr pointing to a dynamically allcated object of T
shared_ptr<T>p(q) //p is a copy of q;increments the count in q.
p=q
p.unique() //Return true if p.use_count() is one
p.use_count() //Return the num of objects sharing with p
e.g.
auto p=make_shared<string>(); //p points to a empty string
We can think of a shared_ptr
as if it has an associated counter,usually referred to as a reference count.Whenever we copy a shared_ptr
,the count is incremented.The counter is decremented when we assign a new value to the shared_ptr
and when the shared_ptr
itself is destroyed, such as when a local shared_ptr
goes out of scope.
Once a shared_ptr
’s counter goes to zero, the shared_ptr
automatically frees the object that it manages.
3.When we want to use dynamic memory
Programs tend to use dynamic memory for one of three purposes:
- They don’t know how many objects they’ll need
- They don’t know the precise type of the objects the need
- They want to share data between several objects
In this section, we’ll talk about the third reason.
In general, when two objects share the same underlying data, we can not unilaterally destroy the data when the object of that type goes away.
To make the problem simpler,let’s define a class StrBlob to see this process.
We can not store the vector directly in a StrBlob object.Member of an object are destroyed when the object itself is destroyed.For example, assume that b1 and b2 are two StrBlobs that share the same vector. If one vector is destroyed then the vector will be destroyed, which means the other object can not access this vector though it is not destroyed.
So, we’ll store the vector in dynamic memory.
class StrBlob{
public:
blabla...
private:
shared_ptr<vector<string>>data;
};