20230808cppsmartpointer

Aug 8, 2023

C++智能指针原理

C++ smart pointer schematic

学很多其他语言,如Java、C#或者其他托管语言(managed languages),看C++时总是觉得到处需要delete是件麻烦的事情。

Learning many other languages, such as Java, C# or ther managed languages, C++ always delete object here and there which is a trouble thing.

而一个方法中如果做了delete某一个对象,不过还未运行到即exception,那么还是产生了leak:

1
2
3
4
5
6
7
void function() {
int* p = new int;

// do something to p

delete p;
}

If process work successfully, that’s ok, but if it meet exception below?

  • process returned in the body, it haven’t come to end to delete
  • process exception but not be catch out

Leak will happen in above situation, or you write everywhere the delete function to prevent leaking? Just for recycle the object, to code dirtily?

Maybe once or twice leaked produced by an object, it could be forgave. But if an loop function constantly produce the leak, it must be a critical.

What is RALL

It’s well known that C++ is Orientate-Object language, when initialize object, system will execute class alloc method. If class object is stored at stack space, such as declare a local variable, then when class object is expire life circle, such as get out of a local variable working field, system will execute class dealloc method; If a class object stored at heap space, such as by using new operation to create a class heap object, then when class object is deleting, such as by executing object’s delete operation, system will also execute class object dealloc method.

The specific skill of C++ will be used to solve the source leak trouble, but how?

modern C++ practice recommend to put source stored at stack. If it is a variable, you can simply define it as local variable, then when code block get out, system will automotive collect source on the stack:

1
2
3
4
5
void function() {
int data = 0;
// do something with data
// when function get out, automotive release data stored stack space
}

When source is stored at heap space, you can use a stack object who use pointer store the object, when the stack object release, the heap object delete manually in the dealloc method:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Helper {
private:
int* data;
public:
Helper() {
data = new int;
}
~Helper() {
delete data;
}
void do_something_with_data() {}
};
void function() {
Helper help;
help.do_something_with_data();
// When function get out, help will be release, then Helper dealloc will be called to delete data;
}

This is C++ RALL [Resource acquisition is initialization].

C++ smart pointer

Sample above look odd, for easily usage for develop, unique_ptr is add to standard library after C++ 11.

unique_ptr belong to Smart Points. Using Smart points to take place sample above, it look like this:

1
2
3
4
5
#include <memory>
void function() {
std::unique_ptr<int> data(new int);
printf("data=%d\n", *data);
}

After using the smart pointer, it doesn’t acquire to define Helper class to manage pointer.

But smart pointer sample above require a pointer, can it be a better way to manage the code?

Yes, after C++ 14, standard add make_unique, this is how to use:

1
std::unique_ptr<int> data = std::make_unique<int>();

Ref

Juejin - 都说 C++ 没有 GC,RAII: 那么我算个啥?