share_ptr memory leak

Here is shared_ There are three common ways to define PTR: shared_ptr sp;// Declare a smart pointer to type int

sp.reset(new int(42));
auto sp1 = make_shared<string>("hello");//sp1 is a smart pointer
shared_ptr sp2(new int(42));

And make_ The shared method is a recommended one. It uses one-time allocation and is relatively safe. We all know which operations will change the count. When the reference count is 0, shared_ The objects managed by PTR are automatically destroyed (embracing smart pointers and saying goodbye to memory leaks), so what will affect the reference count? Assignment example: Auto SP = make_shared(1024);// The reference count for SP is 1
Another example:

auto sp1 = make_shared<string>("obj1");
auto sp2 = make_shared<string>("obj2");
auto sp1 = sp2;

This operation will reduce the reference count of sp1 and increase the reference count of sp2. Some people may not understand why this will reduce the reference count of sp1? Imagine that sp1 points to object obj1 and sp2 points to object obj2. After assignment, sp1 will also point to obj2. That is to say, there will be fewer points to obj1 and more points to obj2. If there are no other shared at this time_ PTR points to obj1, and obj1 will be destroyed. Copy, for example:

auto sp2 = make_shared<int>(1024);
auto sp1(sp2);

This operation causes both sp1 and sp2 to point to the same object. What is easy to ignore about copying is the function passed in as a parameter:
auto sp2 = make_ shared<int>(1024); func(sp2);// The execution of func increases its reference count
You can see a specific example:

#include<iostream>
#include<memory>
void func0(std::shared_ptr<int> sp)
{
    std::cout<<"fun0:"<<sp.use_count()<<std::endl;
}
void func1(std::shared_ptr<int> &sp)
{
    std::cout<<"fun1:"<<sp.use_count()<<std::endl;
}
int main()
{
    auto sp = std::make_shared<int>(1024);
    func0(sp);
    func1(sp);
    return 0;
}
Its operation output is: fun0:2
fun1:1 
``
            
Obviously, fun0,Copy it shard_ptr sp,and fun1,There is no copy, so the former will increase the reference count and the count will change to 2, while the latter will not affect. For the problem of parameter value transfer, please refer to "value transfer and pointer transfer" and "confusing references and pointers".
reset call reset Will decrease the count: sp.reset(). And if sp Is the only one that points to the object, the object is destroyed. Although the way of use should be noted shared_ptr It can avoid memory leakage to a great extent, but improper use may still lead to accidents. Stored in containers shared_ptr If your container contains shared_ptr,When you don't need it later, remember to use it erase Delete those unwanted elements, or because the reference count always exists, its object will never be destroyed unless the container itself is destroyed. Do not initialize multiple with multiple raw pointers shared_ptr Note that the following methods should not be used:
```cpp
#include<iostream>
#include<memory>
int main()
{
    auto *p = new std::string("hello");
    std::shared_ptr<std::string> sp1(p);
    /*Don't do that!!*/
    std::shared_ptr<std::string> sp2(p);
    return 0;
}

This will result in two shared_ptr manages the same object. When one of them is destroyed, the managed object will be destroyed, while when the other is destroyed, the object will be destroyed again. However, in fact, the object is no longer there, resulting in serious consequences. Similar to this situation is to use get() to get the raw pointer, and then initialize another shared pointer_ PTR, or the pointer returned by delete get:

#include<iostream>
#include<memory>
int main()
{
    auto sp = std::make_shared<std::string>("wechat:shouwangxiansheng");
    std::string *p = sp.get();
    std::shared_ptr<std::string> sp2(p);/*Don't do that!!*/
    delete p;/*Don't do that*/
    return 0;
}

If the object is not assigned by new, pass the delegator and unique_ptr is similar to PTR. It can specify the deletion device. delete is used by default. For example:

#include<iostream>
#include<unistd.h>
#include<memory>
void myClose(int *fd)
{
    close(*fd);
}
int main()
{
    int socketFd = 10;//just for example
    std::shared_ptr<int> up(&socketFd,myClose);
    return 0;
}

And unique_ The first and most obvious difference between PTRs is that they are an exclusive object and a shared object. It is precisely because of sharing, including maintaining reference counts, that it brings more overhead than unique_ It's bigger for PTR. In addition, shared_ptr cannot handle arrays directly because it uses delete to destroy objects, while for arrays, delete []. Therefore, you need to specify the delegator:

#include<iostream>
#include<memory>
int main()
{
    auto sp = std::make_shared<std::string>("wechat:shouwangxiansheng");
    std::string *p = sp.get();
    //std::shared_ ptr<int> sp1(new int[10]);// You can't
    std::shared_ptr<int> sp1(new int[10],[](int *p){delete[] p;});
    return 0;
}

lambda expressions are used in the example. But generally speaking, good containers are not used. Why use dynamic arrays? To sum up, the above is shared_ptr basic content, generally speaking, the specification uses shared_ptr can avoid memory leakage to a great extent. Attention, shared_ptr provides, *, - > operations, and does not directly provide pointer operation and [].

Keywords: C++ pointer

Added by aquila125 on Sun, 20 Feb 2022 05:31:38 +0200