有一个值,不等于有有效对象
对象被销毁或其存储被释放以后,程序中仍可能留下指向原位置的值。这类悬垂状态并不会自动变成空指针;因此把一个值与空指针比较,不能单独证明它指向的对象还可以使用。
C++工作草案把空指针、有效对象相关指针和无效指针区分开,并根据存储有效期约束其用途。具体语言还可能对无效指针的求值设有不同限制,所以不能统一假定“只要还没解引用就一定没有问题”。
不只动态释放会产生悬垂
把函数局部对象的地址或引用交给调用者,却没有让对象继续存在,是另一类来源。Rust教材用返回局部String引用的例子说明:函数结束时字符串被清理,返回引用不能凭自己的存在延长该字符串的生命期。
释放后使用描述已经发生的不合法访问,悬垂指针则描述失去有效目标的指针状态。二者紧密相关,却不是同一概念;局部对象过期、释放动态存储等不同路径,都可能留下需要处理的失效访问能力。
有效期必须覆盖所有允许使用
修复时要确定调用者真正需要的是访问、共同持有,还是拥有一个独立值。返回拥有对象的值、让所有者保持存在,或用受管理的共享机制,都可能比返回无生命期约束的原始位置更清楚。
借用检查能够拒绝部分悬垂引用,动态检测器也可以发现已经执行到的栈或堆生命期错误。但工具不会替程序决定正确的业务持有期限;公开接口仍需明确谁保持对象有效、谁可以释放以及何时停止访问。