内存管理之堆
什么是堆
堆(heap)是一种内存管理方式。内存管理对操作系统来说是一件非常复杂的事情,因为首先内存容量很大,其次内存需求在时间和大小块上没有规律(操作系统上运行着的几十、几百、几千个进程随时都会电请或者释放内存,申请或者释放的内存块大小随意)
堆这种内存管理方式特点就是自由(随时申请、释放、大小块随意)。堆内存是操作系统划归给堆管理器(操作系统中的一段代码,属于操作系统的内存管理单元)来管理的,然后向使用者(用户进程)提供API (malloc和free)来使用堆内存。
我们什么时候使用堆内存?需要内存容量比较大时,需要反复使用及释放时,很多数据结构(譬如链表)的实现都要使用堆内存。
我们什么时候使用堆内存?需要内存容量比较大时,需要反复使用及释放时,很多数据结构(譬如链表)的实现都要使用堆内存。
堆管理内存的特点(大块内存、手工分配&使用&释放)
特点一容量不限(常规使用的需求容量都能满足)
特点二:申请及释放都需要手工进行,手工进行的含义就是需要程序员写代码明确进行申请malloc及释放free。如果程序员申请内存并使用后未释放,这段内存就丢失了(在堆管理器的记录中,这段内存仍然属于你这个进程,但是进程自己又以为这段内存已经不用了,再用的时候又会去申请新的内存块,这就叫吃内存),称为内存泄漏。在C/C++语言中,内存泄漏是最严重的程序bug,这也是别人认为Java/C#等语言比c/C+ +优秀的地方。
c语言操作堆内存的接口(malloc free)
堆内存释放时最简单,直接调用free释放即可。 void free(void *ptr) ;
堆内存申请时,有3个可选择的类似功能的函数: malloc, calloc, realloc
void *malloc(size t I size) ;
void *calloc(size_ t nmemb, size_ t size) ; // nmemb个单元,每个单元size字节
void *realloc(void *ptr, size_ t size) ; //改变原来电请的空间的大小的
譬如要申请10个int元素的内存:
malloc(40) ; malloc (10*sizeof (int)) ;
calloc(10,4) ; calloc(10,sizeof (int)) ;
数组定义时必须同时给出数组元素个数(数组大小),而且一旦定义再无法更改。
堆内存申请时必须给定大小,然后一旦电请完成大小不变,如果要变只能通过realloc接口。realloc的实现原理类似于.上面说的Java中的可变大小的数组的方式。
堆的优势和劣势(管理大块内存、灵活、容易内存泄漏)
劣势,需要程序员去处理各种细节,所以容易出错,严重依赖于程序员的水平。