在C ++中管理内存的理念是什么?

时间:2010-09-10 00:06:26

标签: c++ memory-management

为广泛的问题道歉。但是在C ++中管理内存的设计因素是什么? 例如:当程序在退出之前没有释放内存对象时,为什么会出现内存泄漏?是不是一个好的编程语言设计应该维护一个“foo-table”来处理这种情况?我知道我有点天真,但C ++中关于类,结构,方法,接口,抽象类的内存管理的设计理念是什么?

当然,人们不能人道地记住C ++的每一个规范。内存管理的核心驱动设计是什么?

8 个答案:

答案 0 :(得分:40)

  

内存管理的核心驱动设计是什么?

几乎在所有情况下,您都应该使用自动资源管理。基本上是:

  • 在任何可行的情况下,更喜欢创建具有自动存储持续时间的对象(即,在堆栈上,或函数本地)
  • 每当您必须使用动态分配时,请使用范围限制资源管理(SBRM;通常称为Resource Acquisition is Initialization或RAII)。

您很少需要编写自己的RAII容器:C ++标准库提供了一整套容器(例如vectormap)和智能指针,如shared_ptr(来自C ++ TR1,C ++ 0x和Boost)在大多数常见情况下都能很好地工作。

基本上,在非常好的C ++代码中,你永远不应该自己调用delete 1 来清理你已分配的内存:内存管理和资源清理应始终封装在一个某种容器。

1。显然,这里的例外情况是你自己实现一个RAII容器,因为那个容器必须负责清理它拥有的任何东西。

答案 1 :(得分:4)

目前尚不清楚您是在询问C ++中内置的哲学,还是如何以防止内存泄漏的方式使用它。

防止内存泄漏(和其他资源泄漏)的主要方法称为RAII(资源获取是初始化)或SBRM(范围绑定资源管理)。无论哪种方式,基本思想都非常简单:由于具有auto存储持续时间的对象在退出其范围时会自动销毁,因此您可以在此类对象的ctor中分配内存,并释放其内存中的内存。

就C ++本身而言,它并没有真正的哲学。它提供了机制,但由程序员决定哪种机制适合当前的情况。这通常是RAII。有时可能是垃圾收集器。还有一些时候,其他时候可能是各种各样的自定义内存管理器。当然,有时它是两个或全部三个的组合,或完全不同的东西。

编辑:至于为什么 C ++以这种方式做事,它相当简单:几乎任何其他选择都会使语言不适合至少某些类型的问题 - 包括C ++编号的数字很明显是合适的。其中最明显的一个是能够在“裸机”上运行,并且支持结构最少(例如,没有操作系统)

答案 2 :(得分:3)

  

当程序在退出之前没有释放内存对象时,为什么会出现内存泄漏?

好吧,操作系统通常会为你清理乱七八糟的东西。但是,当你的程序运行了一段任意的时间并且你已经泄漏了太多的内存而你又不能分配时会发生什么?你崩溃了,这不好。

  

是不是一个好的编程语言设计应该维护一个处理这种情况的“foo-table”?

没有。有些编程语言有自动内存管理,有些则没有。两种型号都有优点和缺点。具有手动内存管理功能的语言允许您说明分配和释放资源的时间和位置,即,它是非常确定的。然而,相对初学者将不可避免地编写在他们习惯于处理内存管理时泄漏的代码。

自动化方案对于程序员来说非常好,但是你没有获得相同级别的确定性。如果我正在编写硬件驱动程序,这对我来说可能不是一个好模型。如果我正在编写一个简单的GUI,那么我可能并不关心某些对象持续时间比他们需要的时间长,所以我每次都会采用自动化管理方案。这并不是说GC的语言仅用于“简单”任务,有些任务只需要对资源进行更严格的控制。并非所有平台都有4GB +内存供你玩。

您可以使用一些模式来帮助您进行内存管理。规范示例为RAII (Resource Allocation is Initialization)

答案 3 :(得分:3)

C和C ++采取的位置是程序员在完成已分配的内存后知道的。这避免了语言运行时需要了解有关已分配内容的任何内容,以及必要时“清理”所需的相关任务(引用计数,垃圾收集等)。

关键在于:如果你分配它,你必须释放它。 (malloc / free,new / delete)

有几种方法可以帮助您管理,以便您不必明确记住。 RAII和提供容器的智能指针实现对于基于对象创建和销毁来管理内存非常有用和强大。它们可以为您节省数小时的时间。

答案 4 :(得分:1)

哲学方面,我认为有两件事导致C ++没有垃圾收集器(这似乎就是你所得到的):

  • 与C. C ++的兼容性尝试与C非常兼容,无论好坏。 C没有垃圾收集,所以C ++没有,至少在默认情况下没有。我想你可以把它归结为“历史原因”。

  • “你只需支付你所用的费用”的理念。 C ++试图避免在C之上强加任何开销,除非你明确要求它。所以你只需要支付异常的代价,如果你实际抛出一个,等等。有一个论点,无论何时在堆上分配一个对象,垃圾收集都会产生成本,因此它不能成为C ++中的默认行为。

    请注意,关于垃圾收集实际上是否比手动内存管理效率更高或更低,实际上存在很多争论。更好的垃​​圾收集器通常希望能够移动东西,而C ++具有指针算法(同样,继承自C),这使得很难使这样的收集器与C ++一起工作。

这是Stroustrup(并非真正直接)对“Why doesn't C++ have garbage collection?”的回答:

  

如果你想要自动垃圾收集,那么C ++有很好的商业和公共域垃圾收集器。对于适合垃圾收集的应用程序,C ++是一种优秀的垃圾收集语言,其性能可与其他垃圾收集语言相媲美。有关C ++中自动垃圾收集的讨论,请参阅C ++编程语言(第3版)。另见Hans-J。 Boehm的C和C ++垃圾收集站点。

     

此外,C ++支持编程技术,允许内存管理在没有垃圾收集器的情况下是安全和隐式的。

     

C ++ 0x提供GC ABI。

答案 5 :(得分:1)

  

是不是一个好的编程语言设计应该维护一个处理这种情况的“foo-table”?

是吗?为什么?一个好的编程语言可以让你解决问题,不多也不少。 垃圾收集器肯定会降低进入的门槛,但它也会控制程序员,这在某些情况下可能会成为一个问题。诚然,在现代2.5GHz四核计算机上,以及当今先进高效的垃圾收集器,我们可以忍受。但是C ++必须使用更有限的硬件,从具有高达16MB RAM的台式计算机到具有16KB的嵌入式平台,以及介于两者之间的所有内容。它必须在实时代码中可用,您可以暂停程序0.5秒以运行垃圾回收。

C ++不只是设计为桌面计算机上使用的语言。它意味着可以在无处不在,在内存有限的系统,硬实时场景,大型超级计算机和其他任何地方使用。

C ++的指导原则是“你不为你不使用的东西买单”。如果你不想要垃圾收集器,你不必支付一个(陡峭)的价格。

即使没有垃圾收集器,也有非常强大的技术来管理C ++中的内存并避免内存泄漏。如果垃圾收集器是唯一的方式来避免内存泄漏,那么就会有一个强有力的论据支持在语言中添加一个。但事实并非如此。您只需要学习如何在C ++中自己正确管理内存。

答案 6 :(得分:0)

  

内存管理的核心驱动设计是什么?

与自动变速器汽车相比,驾驶设计(没有双关语)有点像直升机变速器汽车。就像一个换挡汽车,C ++让你自由和控制机器,但它不像自动机器那样容易为你处理许多事情。

关于C ++与Java,可以很容易地编写以下内容:

  

驾驶变速车的人知道它们的差异和优势   完全控制您的汽车发动机;用自动驾驶汽车的人   传输没有。 (...)赛车,例如,不使用自动车   传输。 (...)习惯换档的人会更专注   他们的驾驶使其更加高效和安全。

http://www.eslbee.com/contrast_stick_shift_or_automatic.htm

但是,我应该补充一点,C ++确实有一些机制可以为你处理内存,就像其他人提到的那样,例如: RAII,智能指针等。

答案 7 :(得分:-2)

C ++没有内存的设计理念。它只有两个用于分配内存的功能(新的malloc)和两个用于释放内存的功能(免费删除)和一个与frew相关的功能。甚至那些也可以被程序员取代。

这是因为C ++的目标是在通用计算机上运行。通用计算机是CPU,存储器(RAM,各种ROM)和外围设备的总线/总线。通用计算机上没有内置的内存管理。

现在大多数计算机都带有内存(通常是ROM版本),其中包含一个BIOS /监视器。你可能会看到一些基本的内存管理形式 - 可能不是。

有些计算机配备了具有内存管理功能的操作系统,但即使在那里它也经常是原始的,我很容易声称大多数运行C ++程序的计算机都没有操作系统。

如果您希望C ++在任何计算机上运行,​​它就没有内存管理理念。