一、序言
在开发过程中,见识到了cpp的指针的杀伤性,吃了不少苦头。
想要从根本上解决这个问题,需要透彻地理解指针。
二、基本知识:
在计算机中,数据是存放在内存单元中的,一般把内存中的一个字节称为一个内存单元。为了更方便地访问这些内存单元,可预先给内存中的所有内存单元进行地址编号,根据地址编号,可准确找到其对应的内存单元。由于每一个地址编号均对应一个内存单元,因此可以形象地说一个地址编号就指向一个内存单元。C 语言中把地址形象地称作指针。
指针就是地址。而可以保存指针的变量被称为指针变量(*声明)。而&是取地址操作,读取了变量的地址。
(规则等基本知识略……)
特别需要注意的是,指针不能没有合法的指向,必须要对应一块指定的内存空间,随机指向的"野指针"可能会指向我们有用的内存,导致系统崩坏。十分危险。
而这也是cpp编程中常见的错误。
另外,指针的设置也会导致另一个问题,Memory Leak,即内存泄露:
1、内存分配未成功,却使用了它
2、内存分配虽然成功,但是尚未初始化就引用它
3、内存分配成功并且已经初始化,但操作越过了内存的边界
4、忘记了释放内存,造成内存泄露
三、智能指针:
为了避免上边我们所讨论的问题的出现,cpp中设计了一种被称为智能指针的指针。
在我们的所分配的动态内存过期之后,析构函数自己删除所指向的内存,这就是智能指针的原理。
在c++98和11中,分别提供了auto_ptr和unique_ptr,shared_ptr以及weak_ptr。
其中,auto是98的,已经被unique所取代。
我们这里重点学习了后者unique和shared。
但是auto是基本的,也应该看一下。
分类
std::unique_ptr<T>:独占资源所有权的指针。std::shared_ptr<T>:共享资源所有权的指针。std::weak_ptr<T>:共享资源的观察者,需要和 std::shared_ptr 一起使用,不影响资源的生命周期。
unique
所谓的独占资源所有权,就是独占资源时,可以利用此指针进行管理。
当离开此对象的作用域时,会自动释放资源。
使用时比较简单。
不需要delete。
std::unique_ptr<int> uptr = std::make_unique<int>(200); std::unique_ptr<int> uptr1 = uptr; // 编译错误,std::unique_ptr<T> 是 move-only 的
也可以自定义deleter。
shared
对资源做引用计数,当引用计数为0时自动释放资源。
{ std::shared_ptr<int> sptr = std::make_shared<int>(200); assert(sptr.use_count() == 1); // 此时引用计数为 1 { std::shared_ptr<int> sptr1 = sptr; assert(sptr.get() == sptr1.get()); assert(sptr.use_count() == 2); // sptr 和 sptr1 共享资源,引用计数为 2 } assert(sptr.use_count() == 1); // sptr1 已经释放 } // use_count 为 0 时自动释放内存
这个指针需要维护两部分信息,指向共享资源的指针,引用计数等共享资源的控制信息。因此,他的实现对象实际上保存了两个指针。
……还有更复杂的讲解内存的内容,就不写了,可以继续参考文末的博客。
weak
std::weak_ptr 要和std::shared_ptr 一起使用。 一个 std::weak_ptr 对象看做是 std::shared_ptr 对象管理的资源的观察者,它不影响共享资源的生命周期:
没有用到。
四、代码举例:
pcl.makeshare()是个什么东西?
copy the cloud to the heap and return a smart pointer Note that deep copy is performed, so avoid using this function on non-empty clouds. The changes of the returned cloud are not mirrored back to this one
帮助文档
答:他是对于智能指针的一个复制。且深度复制了原对象。
因为是深度复制,所以对于新指针的操作不会影响源对象。
显然,这里的智能指针应该是我们之前提到的shared类型的。
五、说明:
智能指针虽然比指针更先进了一步,避免了部分错误的发生。
但是,这并不意味着完全可以避免,在使用过程中,不当的操作仍然会导致内存泄露等问题的发生。
仍旧需要格外注意。
下面附录的第三篇博客很好地描述了结果。
六、参考资料:
PCL智能指针疑云 <三> 智能指针作为函数的传值参数和传引用参数 - cv_gordon - 博客园 (cnblogs.com)
(1条消息) C++ 智能指针 - 全部用法详解_cpp_learners的博客-CSDN博客_c++ 智能指针使用