杂文(一)智能指针

本文所有杂文知识都摘录至《 深入理解Android内核设计思想(上) [林学森]) 》

智能指针在整个Android工程中广泛使用,特别是在Binder的源码实现中可谓是“比比皆是”,下面来介绍一下智能指针。

1、智能指针的设计理念:

  Java和C/C++的一个重大区别就是它没有“指针”的概念,这并不代表Java不需要使用指针,而是这个“超级武器”隐藏了起来。如果读者曾使用C/C++开发过一些大型项目,就会知道开发人员最头疼的事情莫过于概率性极低的死机问题,而造成系统宕机的根源,往往就是指针异常。所以Java以其他更“安全”的形式向开发人员提供了隐形的“指针”,使得用户既能享受到指针的强大,又能尽量避免指针带来的灾难。
  C/C++项目中常见的指针问题可以归纳为:
  ● 指针没有初始化:
  对指针进行初始化时程序员必须养成的良好习惯,也是指针问题中最容易和控制的一个(其实不仅是指针的初始化,新分配的内存块在进行操作前都应视实际情况进行初始化)。
  ● new 了对象后没有及时delete
  动态分配的内存对象,其生命周期的控制不当常常会引来不少的麻烦。
  当代码数量不多而且这些动态对象只由一名程序员自己维护时,问题通常不打,因为只要稍微留心就可以实现new和delete的配套操作;但是如果一个大型工程(特别是多地协同研发的软件项目),由于沟通的不及时或者人员素质参差不齐,就很可能会出现动态分配的内存没有回收的情况,由此造成的内存泄漏问题往往是致命的。
  比如Function()中new了一个对象,并作为函数结果返回给调用者,那么原则上这个对象就应该有调用者自行delete,但是由于某种原因,调用者并没有执行(或者他不知道要执行)这样的操作,久而久之就会成为系统死机的罪魁祸首。类似的bug因为只在某些特定情况下才会发生(比如内存不足),最后表现出来的问题,就是偶发性系统宕机,要彻底找出这类问题的根源很可能“大海捞针”。
  ● 野指针
  假设有这样一个场景:我们new了一个对象A,并将指针ptr指向这个新对象(即ptr=new A)。当对A的使用结束后,我们也主动delete了A,但唯一没有做的就是将ptr指针置空,这样一个野指针就产生了,因为此时如果有“第三方”试图用ptr使用内存对象A,它首先通过判断发现ptr并不为空,自然而然就认为这个对象还是存在的,其结果也将导致不可预料的死机。
  还有一种更头疼的情况:假设ptr1和ptr2都指向对象A,后来我们通过ptr1释放了A的内存空间,并且将ptr1也置为null;但是ptr2并不知道它所指向的内存对象已经不存在了,此时如果通过ptr2来访问A也会导致同样的问题。
  既然C/C++中的指针有如此有多的隐患倾向,那么我们有没有办法来对它进行适当的改善,这时候就有了智能指针出现意义和价值。
  在分析Android中智能指针的实现原理前,读者应该先思考一下,如果你是智能指针的设计者,你会怎么样去设计智能指针,应该做哪些东西,很显然,前面提到的指针常见问题点是解决的重点。所以问题就转化为,如何设计一个能有效防止以上几个致命弱点的智能指针方案。下一篇杂文会给大家介绍智能指针是如何解决这些问题的,大家也可以自己设计出一套方案,看看能不能比现在Android智能指针设计的更好。

你可能感兴趣的:(杂文(一)智能指针)