Smart pointer and smart pointer
Unlike Java and C #, C ++ does not have a garbage collection mechanism, but it provides a powerful and flexible management mechanism that allows developers to avoid memory leaks. You can use new to obtain the memory or create objects, and delete must be used to release them, so as to avoid Memory leakage. At the same time, the allocation and usage can be encapsulated with classes to ensure no memory leakage.
# Include <iostream>
Using namespace std;
# Include <stdio. h>
# Include <string. h>
Class simpleClass
{
Private:
Char * m_buf;
Size_t m_size;
Public:
SimpleClass (size_t n = 1)
{
M_buf = new char [n];
M_size = n;
}
~ SimpleClass ()
{
Printf ("% d is deleted at % xd \ n", m_size, m_buf );
Delete [] m_buf;
}
Char * GetBuf ()
{
Return m_buf;
}
};
Void foo ()
{
SimpleClass a (10 );
Char * p = a. GetBuf ();
Strcpy (p, "Hello ");
Printf ("% s \ n", p );
}
Int main ()
{
Foo ();
Printf ("exit main ()... \ n ");
Return 0;
}
In this program, the char-type memory allocation is encapsulated in the simpleClass class. By declaring the object and giving the size of the required memory, GetBuf is called to obtain the Response Memory, when an object with simpleClass exists in this section exits, the Destructor will be called and released automatically. However, there are still imperfections. If you add an assignment statement to the foo () function
Void foo ()
{
SimpleClass a (10 );
SimpleClass B =;
Char * p = a. GetBuf (); // added statement
Strcpy (p, "Hello ");
Printf ("% s \ n", p );
}
When simpleClass is implemented, the copy constructor is not implemented. Therefore, the compiler constructs a default copy constructor to execute the bit copy operation, that is, the content of object a is copied to object B in bytes. Therefore, the m_buf in object a and the m_buf in object B after copying point to the memory of the same address. When both a and B are destroyed, the content in m_buf is destroyed twice. Solution:
(1) prohibit copying constructor and declare the copy constructor as private.
(2) Use reference count to maintain a counter for memory usage. When a pointer points to this memory, the counter is incremented by 1. When the pointer pointing to this memory is destroyed, the counter is reduced by 1. Only when the counter is reduced to 0 indicates that no pointer points to this memory, this memory can be released.
# Include <iostream>
Using namespace std;
# Include <stdio. h>
# Include <string. h>
Class simpleClass
{
Private:
Char * m_buf;
Size_t m_size;
Int * m_count;
Public:
SimpleClass (size_t n = 1)
{
M_buf = new char [n];
M_size = n;
M_count = new int; // allocate space for m_count
* M_count = 1;
Printf ("m_count is: % d \ n", * m_count );
}
SimpleClass (const simpleClass & s)
{
M_size = s. m_size;
M_buf = s. m_buf;
M_count = s. m_count;
(* M_count) ++;
Printf ("m_count is: % d \ n", * m_count );
}
~ SimpleClass ()
{
(* M_count )--;
Printf ("m_count is: % d \ n", * m_count );
If (0 = * m_count)
{
Printf ("% d is deleted at % d \ n", m_size, m_buf );
Delete [] m_buf;
Delete m_count;
}
}
Char * GetBuf ()
{
Return m_buf;
}
};
Void foo ()
{
SimpleClass a (10 );
Char * p = a. GetBuf ();
Strcpy (p, "Hello ");
Printf ("% s \ n", p );
SimpleClass B =;
Printf ("B = % s \ n", B. GetBuf ());
}
Int main ()
{
Foo ();
Printf ("exit main ()... \ n ");
Return 0;
}
Analysis: When a is constructed, m_count is initialized to 1. When B = a is executed, count is increased to 2. A and B point to the same memory, and the stored content is "hello ". When exit foo (), B is first destroyed, m_count minus 1, but m_count is still greater than 0, so the memory is not released. When a is destroyed, the m_count value is reduced to 0 to release the corresponding memory.
How to add two codes to the foo () function
Void foo ()
{
SimpleClass a (10 );
Char * p = a. GetBuf ();
Strcpy (p, "Hello ");
Printf ("% s \ n", p );
SimpleClass B =;
// Add code
SimpleClass c (20 );
C =;
Printf ("B = % s, c = % s \ n", B. GetBuf (), c. GetBuf ());
}
After B is created through the copy structure, a c object is declared and the requested memory size is 20 bytes. Then a is assigned to c, and c points to a's memory. C has no pointer to the memory, so it is released. But the program is not processed, causing memory leakage. Solution: Use operator overload.
SimpleClass & operator = (const simpleClass & s)
{
// Determine whether the m_buf and s. m_buf of the current object point to the same address
If (m_buf = s. m_buf)
Return * this;
// If not, the reference count of the current object minus 1.
(* M_count )--;
// If the reference count is 0, the space pointed to by the object will be released.
If (* m_count = 0)
{
Printf ("% d is deleted at % xd \ n", m_size, m_buf );
Delete [] m_buf;
Delete m_count;
}
// The current Object Pointer Points to the new address space
M_buf = s. m_buf;
M_size = s. m_size;
M_count = s. m_count;
(* M_count) ++; // Why is the pointer used for reference counting ??
}
Finally, there is no error, but this smart pointer is not complete, and operations like real pointers, such as operators *,-> are not reloaded. For more details, see page 400 of C ++ Primer.
Recommended books:
C ++ Primer (version 5th)
********** **************************
If you like it, click like and recommend it to your friends.
Add method, in the Public Account
Search: C language daily question
Or: Love_gcc123
You can also press the QR code to add an image.