为什么要使用new和delete?

Noc*_*cta 6 c++ memory-management delete-operator

我是C++的新手,我想知道为什么我甚至不愿意使用新的和删除?它可能导致问题(内存泄漏),我不明白为什么我不应该只是在没有new运算符的情况下初始化变量.有人可以向我解释一下吗?这个具体问题很难谷歌.

Bas*_*tch 5

由于历史和效率的原因,C ++(和C)内存管理是明确的和手动的。

有时,您可能会在调用堆栈上进行分配(例如,使用VLAalloca(3))。但是,这并不总是可能的,因为

  1. 堆栈大小是有限的(取决于平台,为几千字节或几兆字节)。
  2. 内存需求并不总是FIFOLIFO。确实发生了您需要分配内存的情况,该内存将在执行过程中很晚才被释放(或变得无用),特别是因为这可能是某些功能的结果(并且调用方或其调用方将释放该内存)。

您绝对应该阅读有关垃圾回收动态内存分配的信息。在某些语言(Java,Ocaml,Haskell,Lisp等)或系统中,提供了GC,它负责释放无用(更准确地说是不可访问的)数据的内存。另请阅读有关弱引用的信息。请注意,大多数GC需要扫描调用堆栈以查找本地指针。

注意,有可能但很困难的是拥有相当高效的垃圾收集器(但通常在C ++中不是)。对于某些程序,具有显式内存管理功能的Ocaml(具有世代复制的GC)比等效的C ++代码要快。

显式地管理内存具有优点(在C ++中很重要),您无需为不需要的东西付钱。它给程序员增加了很多负担。

在C或C ++中,您有时可能会考虑使用Boehm的保守垃圾收集器。使用C ++时,有时可能需要使用自己的分配器,而不是默认的std :: allocator。另请参阅有关智能指针引用计数std :: shared_ptrstd :: unique_ptrstd :: weak_ptrRAII习惯用语以及三个规则(在C ++中,变为5的规则)。最近的智慧是避免显式newdelete(例如,通过使用标准容器和智能指针)。

请注意,管理内存中最困难的情况是任意(可能是圆形)图形(参考)。

在Linux和其他一些系统上,valgrind是寻找内存泄漏的有用工具。


Bat*_*eba 3

另一种方法是在堆栈上分配,这会给您带来麻烦,因为堆栈大小通常限制为 Mb 数量级,并且您将获得大量有价值的副本。在函数调用之间共享堆栈分配的数据时也会遇到问题。

还有其他选择:一旦不再使用共享指针,使用std::shared_ptr(C++11 起)将为您执行此操作。delete共享指针实现利用了一种可怕的缩写 RAII 所指的技术。我明确提到它是因为大多数资源清理习惯都是基于 RAII 的。您还可以利用 C++ 标准模板库中提供的全面数据结构,这样您就无需费力进行显式内存管理。

但形式上,每个都 new必须用 来平衡delete。对于new[]和也是如此delete[]