位置正确,还要时机正确
数组越界属于访问超出允许范围的问题,而释放后使用则是在原对象已失效以后继续访问。两者可能涉及相同的数值地址,却违反不同的约束:在分配范围内不等于对象仍然存在,对象存在也不等于任何索引都有效。
具体语言还有对齐、值表示和别名等要求。Rust参考手册列出的未定义行为包含悬垂或未对齐指针的访问,以及违反引用规则的行为;所以内存安全不能缩减为“运行时没有出现段错误”。
约束、检查与安全接口
语言可以用静态规则阻止某些非法程序,也可以在运行时检查范围与访问状态。Rust的所有权和借用规则参与前一种保障;需要执行裸指针操作时,unsafe实现必须自行满足相应的安全条件。
unsafe并不会关闭Rust中所有类型或借用检查,也不意味着代码必然出错。安全抽象的重要任务,是把额外责任约束在实现内部,并确保调用者按公开安全接口使用时仍不会触发未定义行为。
测试证据与完整保证的区别
AddressSanitizer通过编译器插桩和运行时库检查实际执行中的多类内存错误,包括堆、栈与全局对象越界、释放后使用和部分栈生命期错误。它帮助定位故障,但一次未报告错误的执行,并未覆盖程序所有可能路径。
检测也有资源和适用条件:AddressSanitizer文档说明了内存开销、平台差异与生产使用边界。另一方面,Rust允许安全地抑制析构,说明资源泄漏与导致未定义行为的非法访问也不能直接画等号。