是否可以创建编码标准或使用可以证明可以消除C ++中任何内存管理错误的库?
我正在考虑像Java这样的东西,例如在Java应用程序中悬挂指针是不可能的。
答案 0 :(得分:7)
是否可以创建编码标准或使用可以证明可以消除C ++中任何内存管理错误的库?
是和否。
即使您使用非常严格的标准,这样做也会限制您使用非常狭窄的C ++语言子集。例如,Power of Ten (Rules for Developing Safety-Critical Code)表示您应该完全禁用堆使用。然而,仅凭这一点并不能阻止您创建内存损坏。
我认为如果对这个问题有一个确切的答案,那么这个行业几十年前就已经解决了,但我们在这里......
我认为没有明确的方法可以确保您的代码完全安全,但有最佳做法可以帮助您确保尽可能少的问题。
以下是一些建议:
shared_ptr
,unique_ptr
等智能指针。但是,如果您愿意,您仍然可以滥用这些内容。 (例如,如果您有循环引用,shared_ptr
将无法帮助您。)valgrind
等内存检查工具,它可以帮助您发现问题并验证您的代码是否没有错误。即使您遵守任何编码标准或最佳做法,也会发生错误。没有人保证你会安全。但是,通过遵循这些建议,您可以最大限度地减少错误的可能性和影响。
答案 1 :(得分:1)
是否可以创建编码标准或使用库 可以证明这可以消除C ++中的任何内存管理错误吗?
没有
但Java也是如此。虽然Java不技术上允许内存泄漏,但如果你不这样做,它确实会在实践中发现它们(和其他资源泄漏)注意。
一个典型的例子,在Android世界中特别熟知,就是当一个程序运行的时间越长,监听器实例的集合越来越多,因为监听器忘记取消注册自己。当侦听器是某个窗口或视图类的实例时,这会在GUI应用程序中快速导致数百MB 泄漏,从而使自己引用大图形。由于所有内存仍然可以访问,因此垃圾收集无法清除它。
你没有技术上丢失指针(它仍然在集合中)的事实对你没有任何帮助。恰恰相反;这是泄漏的原因,因为它可以防止垃圾收集。
与上述相同,虽然Java技术上不允许悬空指针,但类似的错误可能会导致您访问某个窗口或视图对象的指针,该对象仍然在您的程序的有效内存区域中但不应再存在,不再可见。虽然指针访问本身不会导致任何崩溃或问题,但其他类型的错误或崩溃(如NullPointerException
)通常很快就会出现,因为程序逻辑搞砸了。
这个坏消息太多了。
好消息是,如果您遵循简单的指南,这两种语言都可以让您减少内存管理问题。就C ++而言,这意味着:
std::vector
或std::set
)。std::unique_ptr
。std::shared_ptr
。new
,因为现有的标准容器类(如std::vector
或std::set
)不适用于您的用例。不过,这应该是极为罕见的情况。还有Boehm garbage collector for C++,但我从未亲自使用过它。