项目实训(11)指针,智能指针,pcl的智能指针

一、序言

在开发过程中,见识到了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是基本的,也应该看一下。

分类

  1. std::unique_ptr<T> :独占资源所有权的指针。
  2. std::shared_ptr<T> :共享资源所有权的指针。
  3. 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类型的。

五、说明:

智能指针虽然比指针更先进了一步,避免了部分错误的发生。

但是,这并不意味着完全可以避免,在使用过程中,不当的操作仍然会导致内存泄露等问题的发生。

仍旧需要格外注意。

下面附录的第三篇博客很好地描述了结果。

六、参考资料:

指针,C语言指针完全攻略 (biancheng.net)

PCL智能指针疑云 <三> 智能指针作为函数的传值参数和传引用参数 - cv_gordon - 博客园 (cnblogs.com)

(1条消息) C++ 智能指针 - 全部用法详解_cpp_learners的博客-CSDN博客_c++ 智能指针使用

(1条消息) C语言中的指针和内存泄漏几种情况_瑟提曼的海的博客-CSDN博客_c语言 内存泄漏

现代 C++:一文读懂智能指针 - 知乎 (zhihu.com)


版权声明:本文为m0_49088083原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。