Smart pointers in C++ (1/3)

Table of contents

Why use smart pointers

The role of smart pointers

for example

The smart pointer used at the beginning - auto_ptr

Instructions

for example

advanced use

The call result at this time

Contrast using smart pointers

example

result

call function method

example

result

There are three functions commonly used by smart pointers

get() returns the address of the pointer managed by the smart pointer

example

result

release() cancels the hosting of smart pointers to dynamic memory

example

result

reset() Reset the memory address managed by the smart pointer. If the address is inconsistent, the original one will be destroyed

Precautions

Disadvantages of auto_ptr and why it was eliminated in C++11

next section

Reference article (thanks to the big guy)


Why use smart pointers

The main purpose of using smart pointers is to manage dynamically allocated memory to ensure that it is properly freed when it is no longer needed, avoiding problems like memory leaks and dangling pointers.

The role of smart pointers

A smart pointer is an object that encapsulates a raw pointer and provides automatic memory management. Compared with traditional raw pointers, smart pointers have the following advantages:

  1. Automatic release of memory: The smart pointer uses the principle of RAII (resource acquisition is initialization), allocates memory when it is created, and automatically releases memory when it is destroyed. There is no need to manually manage memory release, which avoids memory leaks caused by forgetting to release memory.

  2. Avoid dangling pointers: The smart pointer will automatically release the memory when the object it manages is no longer needed, and set the pointer to null, avoiding the dangling pointer problem, that is, pointing to the released memory area.

  3. Exception safety: Smart pointers ensure that resources are properly released in the event of an exception because their destructors are automatically called when the object is destroyed.

  4. Convenience and ease of use: smart pointers provide operator overloading similar to raw pointers, making it more convenient and intuitive to use.

In short, the use of smart pointers can improve the reliability and security of the code, and reduce the workload of manual memory management, which is a recommended practice in modern C++ programming.

for example

#include <iostream>
#include <memory>
#include <vector>
using namespace std;
void Function_1()
{
	int *a=new int;
	*a = 12;
	//省略其他代码
	if (true)
	{
		return;
		//此时已经跳出循环所以不执行下面的删除指针a
	}
	delete a;
}
int main()
{
	Function_1();
	//这时a指针没有被释放
	return 0;
}

At this time, the a pointer is not released in time during the process of executing the program. This is just a simple example.

In a real situation, it is not the only a that has not been released. Even in some loops, if the pointer is released, the result will be disastrous, and it will be very difficult for you to eliminate some errors.

It is a good habit and a good solution to remember to release the pointer in time every time. but it's very difficult

At this time, you can use the smart pointer solution

The smart pointer used at the beginning - auto_ptr

auto_ptr is a smart pointer template defined by c++ 98, which defines the object that manages the pointer, and the address obtained by new (directly or indirectly) can be assigned to this object. When the object expires, its destructor will use delete to free the memory!

Instructions

Need to be defined in the header file before using

 #include < memory >

Usage is

auto_ptr<type> variable name (new type)

for example

auto_ptr<int> sum(new int(20));//这是定义一个int类型的智能指针
auto_ptr< string > str(new string("你好,我叫mumuemhaha"));//这是定义一个string类型的智能指针

advanced use

At this point, you must have understood how auto_ptr is defined

Let's increase the difficulty a little bit again

At this point we call the first class

#include <iostream>
#include <memory>
#include <vector>
using namespace std;
class Test_1 {
public:
	Test_1() { cout << "Test_1的构造函数" << endl; }
	~Test_1() { cout << "Test_1的析构函数" << endl; }

	int getsum() { return this->sum; }

private:
	int sum = 20;
};

int main()
{
	Test_1* test_1 = new Test_1;
	return 0;
}

The call result at this time

Test_1的构造函数

D:\C++\调试\x64\Debug\调试.exe (进程 23424)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

At this time, since we did not delete the pointer, the destructor was not called

Contrast using smart pointers

At this time, we only need to use smart pointers (the previous class is not typed)

example

int main()
{
	auto_ptr<Test_1> test_1(new Test_1);
	return 0;
}

result

Test_1的构造函数
Test_1的析构函数

D:\C++\调试\x64\Debug\调试.exe (进程 21956)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

At this time, even if we did not delete the pointer, but after the function cycle ends, it will delete our pointer by default.

call function method

The method of calling the function of the variable of the pointer is still the same as that of the ordinary pointer

example

int main()
{
	auto_ptr<Test_1> test_1(new Test_1);
	cout << test_1->getsum()<< endl;
	return 0;
}

result

Test_1的构造函数
20
Test_1的析构函数

D:\C++\调试\x64\Debug\调试.exe (进程 8472)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

There are three functions commonly used by smart pointers

get () returns the address of the pointer managed by the smart pointer

example

int main()
{
	auto_ptr<Test_1> test_1(new Test_1);
	cout << test_1.get()<< endl;
	return 0;
}

result

Test_1的构造函数
0000029FEC3B6360
Test_1的析构函数

D:\C++\调试\x64\Debug\调试.exe (进程 17760)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

release () unmanages smart pointers to dynamic memory

example

int main()
{
	auto_ptr<Test_1> test_1(new Test_1);
	Test_1* a = test_1.release();
	return 0;
}

result

Test_1的构造函数

D:\C++\调试\x64\Debug\调试.exe (进程 23712)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

At this time, you will find that there are only constructors and no destructors. At this time, because test_1 has been managed by a, if you need to release it, you must release it manually (or use another smart pointer to manage it)

reset () Reset the memory address managed by the smart pointer. If the address is inconsistent, the original one will be destroyed

This is not an example, it is to reset the pointer. Note that it can be "variable.reset()" or "variable.reset(new Test_1)"

Precautions

  • Try not to define auto_ptr pointers as global variables or pointers (this will be meaningless compared to other pointers)
  • Don't assign an auto_ptr smart pointer to another smart pointer of the same type unless you know the consequences like this
  • auto_ptr<Test_1> t1(new Test);
    auto_ptr<Test_1> t2(new Test);
    t1 = t2;	// 不要这样

Disadvantages of auto_ptr and why it was eliminated in C++11

One In the second note, because the expression t1=t2 means that the ownership of the data pointed to by the t2 pointer is transferred to t1, and the pointer of t2 is cleared. This does not match my usual intuition

Second, it is for this reason, so it is best not to use auto_ptr pointers in STL containers (because the value of the container must support assignment)

Three does not support memory management of object arrays, such as

auto_ptr<int[]> array(new int[5]);

Therefore, C++11 and later used the more rigorous unique_ptr to replace auto_ptr!

next section

C++ smart pointer (2/3)_木木emhaha's blog-CSDN blog automatically releases memory: smart pointer uses the principle of RAII (resource acquisition is initialization), allocates memory when it is created, and automatically releases memory when it is destroyed. Manually manage memory release to avoid memory leaks caused by forgetting to release memory. Unique_ptr is a smart pointer with exclusive ownership. Only one unique_ptr can point to an object at a time. When unique_ptr is destroyed, the object will be released. At the beginning, p1 hosts the pointer of str, and later p2 takes over the str pointer and cancels the hosting of p1, so that the p1 pointer points to NULL (empty), thus reporting an error. This is because of the exclusivity of auto_ptr and unique_ptr. https://blog.csdn.net/mumuemhaha/article/details/131689322?spm=1001.2014.3001.5502

Reference article (thanks to the big guy)

C++ Smart Pointer - Detailed Explanation of All Usage_cpp Smart Pointer Features_cpp_learners' blog-CSDN blog blood lesson If I don't learn smart pointers, I lost a job. _cpp smart pointer features https://blog.csdn.net/cpp_learner/article/details/118912592

Guess you like

Origin blog.csdn.net/mumuemhaha/article/details/131668974