首先,让我说我理解我所描述的问题如何以及为什么会发生。我是计算机科学专业的,我了解上溢/下溢和有符号/无符号算术。(对于不熟悉该主题的人,Apple 的安全编码指南简要讨论了整数溢出。)
我的问题是关于在检测到此类错误后报告并从中恢复,尤其是在 Objective-C 框架的情况下。(我编写和维护CHDataStructures。)我有一些集合类,它们为存储对象分配内存并根据需要动态扩展。我还没有看到任何与溢出相关的崩溃,可能是因为我的测试用例大多使用健全的数据。但是,考虑到未经验证的值,事情可能会很快爆发,我想防止这种情况发生。
我已经确定了至少两种可能发生这种情况的常见情况:
- 调用者将一个非常大的无符号值(或负符号值)传递给
-initWithCapacity:
. - 添加了足够多的对象导致容量动态扩展,并且容量已经增长到足以导致溢出。
简单的部分是检测是否会发生溢出。(例如,在尝试分配length * sizeof(void*)
字节之前,我可以检查是否length <= UINT_MAX / sizeof(void*)
,因为未通过此测试将意味着产品将溢出并可能分配比预期小得多的内存区域。在支持它的平台上,checkint.h API是另一种选择。)更难的部分是确定如何优雅地处理它。在第一种情况下,调用者可能更有能力(或至少在心态上)来处理失败。第二种情况可能发生在将对象添加到集合的代码中的任何位置,这可能是非常不确定的。
那么,我的问题是:在这种情况下发生整数溢出时,“好公民”Objective-C 代码应该如何行动?(理想情况下,由于我的项目是一个与 Cocoa 中的 Foundation 精神相同的框架,我想模拟它的行为方式以实现最大的“阻抗匹配”。我发现的 Apple 文档在关于这一切。)我认为无论如何,报告错误是给定的。由于添加对象的 API(这可能导致场景 2)不接受错误参数,如果有的话,我真的可以做些什么来帮助解决问题?在这种情况下,什么才是真正可以接受的?如果我能做得更好,我不愿意故意编写容易崩溃的代码......