分类:
2009-03-28 15:56:49
前两天在CU的论坛上看到一个帖子, 《进程死亡前,malloc 或者 calloc 得到的内存被free之后不能被OS重用吗?》, 链接地址。
今天在看《C++沉思录》时,在第2章《为什么用C++》中关于抽象的那一节讲到了相关问题。
操作系统提供了一定程度的保护,而编程语言通常没有。那些编写新的抽象给其他程序员用的程序员,往往不得不依靠用户自己去遵守编程语言技术上的限制。这些用户不仅要遵守语言的规则,还要遵循其它程序员制定的规范。
例如, 由malloc函数实现的动态内存的概念就是C库中经常使用的抽象。你可以用一个数字作参数来调用malloc, 然后它在内存中分配空间,并给出地址。当你不再需要这块内存时,就用这个地址作参数来调用free函数,这块内存就返回给系统留作它用。
在很多情况下,这个简单的抽象都相当有用。不论规模大小,很难想象一个实际的C程序不使用malloc或者free, 但是要成功的使用抽象,必须遵循一些规范。要成功的使用动态内训,程序员必须:1知道要分配多大内存。2不使用超出分撇的内存范围外的内存。3不再需要时释放内存。4只有不再需要时, 才释放内存。4只有不再需要时,才释放内存。5只释放分配的内存。切记检查每个分配请求,以确保成功。要记住的东西很多,而且一不留神就会出错。如果正在编写一个使用了动态内存的程序,就难免要允许你的用户释放掉任何由他们分配的内存,这些内存的分配是他们对程序调用请求的一部分。
有些语言通过垃圾收集(garbage collection)来解决这个问题,这是一种当内存空间不再需要时自动回收内存的技术。垃圾收集使得编写程序时能更方便的采用灵活的数据结构,但要求系统在运行速度、编译器和运行时系统复杂度方面付出代价,另外,垃圾收集只回收内存,不管理其它资源。C++采用了另外一种更不同寻常的方法:如果某种数据结构需要动态分配资源,则数据结构的设计者可以在构造函数和析构函数中精确定义如何释放该结构所对应的资源。
这种机制不是总像垃圾收集那样灵活,但是在实践中,它与许多应用更接近。另外,与垃圾收集相比起来它有一个明显的优势, 就是对环境要求低很多:内存一旦不用了就会被释放,而不是等待垃圾收集机制发现之后才释放。