Global objects: Assign at startup, destroy at end
Local object: Within the program block, outside the program block
Static object: First use assignment, destroy at end
Dynamic memory uses new to allocate objects, using Delete to destroy objects
12.1 Two Smart pointers
#include <memory>
shared_ptr: Multiple pointers can point to the same object
UNIQUE_PTR: Exclusive-pointing objects
Weak_ptr: A companion class that points to the shared_ptr managed object, which is a weak reference
A smart pointer is also a template that needs to be defined to indicate the type
Shared_ptr<string> P1;
shared_ptr<list<int>> P2;
Default initialized to null pointer
shared_ptr and Unique_ptr operations that are supported |
Unique_ptr<t> up Shared_ptr<t> SP |
An empty smart pointer to an object of type T |
P |
As a condition, pointing to an object is true |
*p |
Dereference to get the object pointed to |
P->item |
Equivalent to (*p). Item |
P.get () |
Returns the saved pointer in P |
Swap (p, q) P.swap (q) |
Swapping pointers in P and Q |
shared_ptr Unique Operation |
Make_shared<t> (args) |
Returns an shared_ptr that initializes the object of T with args |
Shared_ptr<t> p (q) |
P is a copy of Q, pointing to the same object, and the counter increments in Q |
P=q |
Decrements the reference count in P and increments the reference count in Q |
P.unique () |
Returns True if P.use_count () is 1 |
P.use_count () |
Returns the number of smart pointers for shared objects, very slowly, for debugging |
Three reasons to use dynamic memory
- Program does not know how many objects to use
- The program does not know the exact type of object required
- Programs need to share data between multiple objects
12.1.2 Direct Memory Management
int*ptr =New int;//default initialization, value not definedint*PTR1 =New int();//value is initialized to 0int*PTR2 =New int(1024x768); Const int*PTR3 =New Const int(1024x768);int*PTR4 =New(nothrow)int(1024x768);//allocation failed, not throwing Bad_alloc exception, but returning null pointerstring*str =New string;//default initialized to empty stringstring*STR1 =New string();//value is initialized to an empty stringstring*STR2 =New string("string"); Vector<int> *PV =Newvector<int>{1,2,3,4,5};auto P=NewAuto"123");//for const char**Auto P =NewAutostring("123"));//to string*intI, *pi1 = &i, *pi2 =nullptr;Double*PD =New Double( -), *PD2 =PD;DeleteI//error, I is not a pointerDeletePI1;//undefined, PIL is a local variableDeleteOdd//SuccessDeletePD2;//Undefined, PD2 has been releasedDeletePI2;//succeeded, releasing a pointer to null
After releasing the memory, the pointer becomes a dangling pointer (dangling pointer), usually still points to the original memory address, and if the delete again later destroys free-space memory, it is often necessary to re-assign nullptr.
12.1.3 combined with shared_ptr and new
shared_ptr<int> p2 =New int( the);//error int* cannot be implicitly converted to smart pointershared_ptr<int> P2 (New int( the));//correct, because the constructor is explicit, the upper is not trueint* Q =New int(Ten); shared_ptr<int> P (q, [] (int* p) {cout << *p;DeleteP });//Customizing how memory is Freed
Combined use is not recommended
Other operations
shared_ptr<int> P (newint(9int *pi = p.get(); get built-in pointer if (!p.unique ())/// not unique reference p.reset (new int1)); // change the direction of p without affecting the values of other references 1; // The only reference, the direct change does not affect the other
12.1.4 Smart pointers vs. Net using
void F (destination &D) { = connect (&D); // ensure that C is released after the program ends Shared_ptr<connection> p (&c, [] (auto c) {delete c;}); ...}
12.1.5 Exclusive Smart pointer unique_ptr
Unique_ptr cannot be assigned, copy operation
unique_ptr<int>= nullptr; // release the object of U, and place the empty u.release (); // release the object control of U and return the built-in pointer, empty uu.reset (); // release the object of U u.reset (q); // point to Q, release the object of U
You can copy and return a unique_ptrthat will be destroyed , such as a copy of the parameter when it is returned, which is actually a special copy (13.6.2).
Custom deletes need to indicate the type at definition, which differs from shared_ptr as a parameter.
unique_ptr<int, decltype (process) *> u (newint(ten), process);
12.1.6 retarded can pointer weak_ptr
The weak_ptr will be bound to a shared_ptr, which will not change the shared_ptr reference count.
mentally retarded can be used shared_ptr object initialization.
shared_ptr<int> u1 (New int( -)); weak_ptr<int> w =U1;w.reset ();//Empty WW.use_count ();//number of shared shared_ptrW.expired ();//User_count is 0, returns True, otherwise falseW.Lock();//returns the corresponding Shared_ptr object, if expired is true, returns an empty objectif(shared_ptr<int> U = w.Lock())//can judge and get shared_ptr
12.2 Dynamic arrays
It is best to use containers from other standard libraries, such as vectors, strings, which can use the default versions of copies, assignments, and destructors, and use dynamic arrays for your own consideration.
The new 12.2.1 array
int New int [ten]; // 10 Uninitialized int New int [Ten] (); // 10 values are initialized to 0 int New int [1,2,3 }; // The first three are three-to-one, others are 0
- It is important to note that the allocated memory space is not an array type space, but only a memory space, and returns a first address.
- Performs the default initialization using the object assigned by new.
Need to use when releasing
Delete [] PIA;
For how to know in-memory size in delete at release time, a generic compiler is freed by recording the allocated memory size before allocating the dynamic array, and then releasing it when the record is freed.
Managing dynamic arrays with smart pointers
unique_ptr<int []> u (new Span style= "color: #0000ff;" >int [10 ]); cout << U[10 ] << Endl;u.release (); // can automatically call delete [] shared_ptr <int > Sp (new int [10 ], [] (int *p) {delete [] p;}); // Sp.reset (); // Use the custom destroy function
SHARED_PTR does not directly support dynamic array management, so it does not support subscript operations and pointer arithmetic operations, and you must use get to get built-in pointers when needed.
Allocator<t> A |
Defines a allocator object that allocates memory for an object of type T |
A.allocate (N) |
allocating memory for N T-type objects |
A.deallocate (P, N) |
Reclaim memory allocated for N T-type objects |
A.construct (p, args) |
Constructs a T object where P points (requires a construct) |
A.destroy (P) |
Destroys the T object where P points (requires one destroy) |
intCount =Ten; allocator<string>A;//Allocating Memorystring* p =a.allocate (count); for(inti =0; I < count; i++) a.construct (P+ i);//Constructing Objects for(inti =0; I < count; i++) A.destroy (P+ i);//destroying Objects//Recover MemoryA.deallocate (P, count);
Uninitialized_copy (B,E,B2) |
Objects in the range from iterators B through E, copied inside to B2 memory |
Uninitialized_copy_n (B,N,B2) |
N-Elements copied from iterator B to B2 memory |
Uninitialized_fill (b,e,t) |
Create a copy of T in the range B to E |
Uninitialized_fill_n (b,n,t) |
Create a copy of T in N-element memory starting at B |
12th Chapter Dynamic Memory