是否可以创建一个编码标准或使用可以证明可以消除 C++ 中的任何内存管理错误的库?
我正在考虑类似 Java 的东西,例如,在 Java 应用程序中不可能有悬空指针。
是否可以创建一个编码标准或使用可以证明可以消除 C++ 中的任何内存管理错误的库?
我正在考虑类似 Java 的东西,例如,在 Java 应用程序中不可能有悬空指针。
是否可以创建一个编码标准或使用可以证明可以消除 C++ 中的任何内存管理错误的库?
是和不是。
即使您使用非常严格的标准,这样做也会将您限制在 C++ 语言的一个非常狭窄的子集中。例如,十的幂(开发安全关键代码的规则)说您应该完全禁用堆使用。但是,仅此一项并不能阻止您创建内存损坏。
我认为如果这个问题有一个确切的答案,这个行业几十年前就已经解决了,但我们在这里......
我不认为有确定的方法可以确保您的代码完全安全,但是有一些最佳实践可以帮助您确保尽可能少地出现问题。
以下是一些建议:
shared_ptr
。unique_ptr
当然,如果你愿意,你仍然可以滥用这些。(例如shared_ptr
,如果您有循环引用,则不会帮助您...)valgrind
,它可以帮助您发现问题并验证您的代码没有错误。即使您遵循任何编码标准或最佳实践,错误也可能而且将会发生。没有人保证你会安全。但是,通过遵循这些建议,您可以最大限度地减少错误的机会和影响。
是否可以创建一个编码标准或使用可以证明可以消除 C++ 中的任何内存管理错误的库?
不。
但是对于 Java 也是如此。虽然 Java 在技术上不允许内存泄漏,但如果您不注意,它在实践中确实存在内存泄漏(和其他资源泄漏)。
一个在 Android 世界中广为人知的经典示例是,当程序运行的时间越长,侦听器实例的集合就会不断增长,因为侦听器会忘记注销自己。当侦听器是某个窗口或视图类的实例时,这可能会迅速导致数百 MB泄漏在 GUI 应用程序中,该类将自身保持对大图形的引用。由于所有这些内存仍然可以访问,垃圾收集无法清理它。
从技术上讲,您没有丢失指针(它仍在集合中)这一事实对您毫无帮助。恰恰相反; 这是泄漏的原因,因为它阻止了垃圾收集。
与上述相同,虽然 Java 在技术上不允许悬空指针,但类似的错误可能会导致您访问指向某些窗口或视图对象的指针,该对象仍然在您的程序的有效内存区域中,但应该不再存在并且是不再可见。虽然指针访问本身不会导致任何崩溃或问题,但NullPointerException
由于程序逻辑混乱,其他类型的错误或崩溃(如 a )通常很快就会出现。
坏消息就这么多。
好消息是,如果您遵循简单的指南,这两种语言都可以减少内存管理问题。就 C++ 而言,这意味着:
std::vector
或)。std::set
std::unique_ptr
.std::shared_ptr
.new
仅当您实现一些低级容器类时才使用bare ,因为现有的标准容器类(如std::vector
or std::set
)不适用于您的用例。不过,这应该是极其罕见的情况。还有用于 C++ 的 Boehm 垃圾收集器,但我从未亲自使用过它。