C语言内存动态分配与释放

一、内存分配

对于内存的分配,主要采用的是标记法。

分配方法有两种,一种是静态分配,也就是在程序编译的时候,就完成了对内存的分配。例如当一个数组在声明时,指定长度之后,它所需要的内存在编译时就会被分配。

另一种方法是动态分配,动态分配是指程序在运行时为它分配内存。

分配内存的时候,对于已分配的内存,操作系统会给一个标记,未分配的内存,操作系统也会有一个标记,操作系统辨别内存是否可以使用就是通过标记判断,当内存释放的时候,就会修改标记。

二、动态分配

C函数库关于内存的动态分配和释放提供了四个函数malloc、calloc、realloc和free。其中前三个是执行内存动态分配,最后一个是执行释放。

1、void *malloc(size_t size)

malloc函数所需要的参数是要分配的字节长度,例如

对于上面的代码,如果一个整数占有四个字节的话,将会分配25个整数的内存。为了增加代码的可移植性,如果要分配25个整数的内存,应将代码改为

在molloc函数分配内存时,会从内存中提取一块合适大小的内存,并返回该块内存的首地址,这块内存并没有被初始化。对于这种方法,必然会有问题出现,就是可用内存的大小不能满足请求所需要的内存,此时,malloc函数返回NULL。所以,使用malloc函数分配内存之后,并不能保证内存分配成功,在使用的时候,应该先判断指针是否为NULL,如果不为NULL,则说明分配成功,可以使用。否则,反之。

2、void *calloc(size_t num_elements,size_t element_size)

calloc函数所需要的参数是元素的个数和元素的字节长度,之所以要这两个参数,是因为使用calloc函数在分配内存的时候,会对内存进行初始化,如果要初始化,就需要知道一个元素是多大,为了计算总的内存大小,还应该知道元素的个数。

calloc函数与malloc函数的主要差别就是在返回首地址的指针之前,对进行了初始化,如果在程序只是想将一些值存放到数组中,那么这个初始化就纯属浪费。

3、void *realloc(void *ptr,size_t new_size)

relloc函数需要的参数为原来内存的首地址新的内存的长度。

realloc函数用于修改已经分配内存的大小,使用这个函数可以将一块内存扩大或缩小。如果扩大一块内存,那么这块内存原先的内容必然会被保留,新增加的内存添加到原来内存的后面;如果缩小,对于尾部的内存会被释放。

对于扩大内存,依然存在内存不够的问题,如果分配不成功,就会返回NULL。除此之外,还有另一个问题,就是扩大内存的时候,不可修改原来内存的大小,此时系统将会重新分配一块内存,将原来内存的数据复制到新的内存中,所以使用realloc函数修改内存大小之后,应该使用realloc函数返回的指针而不是原来的指针。

4、void free(void *pointer)

free函数所需要的参数是一个指针,功能是将指针指向的内存区域释放(通过修改标记实现),以便内存可以重新使用。

free函数释放的只是指针指向的内存,指针所占用的空间并未被改变,调用free函数之后,指针所指向的地址仍然不变,如果在程序的后面,重新分配到了该指针指向的内存,使用现在的指针也可访问,但是不安全。此时,该指针被叫做野指针,为了避免野指针,应在调用free函数之后,将指针的值置为NULL。

posted @ 2012-05-16 08:49  Java EE  阅读(496)  评论(0编辑  收藏  举报