0%

C语言 动态内存分配

动态内存分配

为什么使用动态内存分配

比如,我们计算年级学生的平均成绩,但是不知道有多少学生,可以定义一个很大的数组,确保学生个数不会超出数组定义范围,但是如果学生人数很少,就会造成巨大的浪费。所以会有如下缺点:

  • 数组声明中引入了人为的限制,如果程序需要使用的元素数量超过了声明的长度,它就无法处理这种情况;
  • 要避免上述情况,需要把数组声明的更大些,但这也导致如果元素数据比较少时,巨型数组的绝大部分内存空间都浪费了;
  • 如果输入的数据超过了数组的容纳范围,程序必须以一种合理的方式作出响应,而不应该由于一个异常而失败,也不应该打印出看上去正确但实际上错误的结果。

malloc和free

c函数库提供了两个函数,malloc和free,分别用于执行内存分配和释放。这些函数维护一个可用内存池。当一个程序另外需要一些内存时,它就调用malloc函数,malloc从内存池中提取一块合适的内存,并向该程序放回一个指向这块内存的指针。注意,现在这块内存并没有以任何方式进行初始化。

free的参数要么是NULL,要么是一个先前从malloc、calloc或realloc返回的值。向free传递一个NULL参数不会产生任何效果。

And我们知道malloc的返回值为void *,所以malloc可以指向任何类型的整数、浮点值、结构或者数组,这个需要我们自己定义。

calloc和realloc

malloc和calloc之间的主要区别是后者在返回指向内存的指针之前把它初始化为0。这个初始化常常能带来方便,但是如果你的程序只是想把一些值存储到数组中,那么这个初始化过程就纯属浪费时间;两者的另外一个较小的区别是它们请求内存数量的方式不同,calloc的参数包括所需元素的数量和每个元素的字节数。

realloc函数用于修改一个原先已经分配的内存块的大小。如果原先的内存块无法改变大小,realloc将分配另一块正确大小的内存,并把原先那块内存的内容复制到新的块上。

如果realloc函数的第一个参数是NULL,那么它的行为就和malloc一摸一样。

常见的动态内存错误

使用动态内存常犯的错误就是忘记检查所请求的内存是否成功分配?第二大错误是操作内存时超出了分配内存的边界。

分配内存但在使用完毕后如果不释放将引起内存泄露memory leak。

内存分配实例

动态内存分配一个常见的用途就是为那些长度在运行时才知的数组分配内存空间。

总结

  • 当数组被声明时,必须在编译时知道它的长度。动态内存分配允许程序为一个长度在运行时才知道的数组分配内存空间;
  • 动态内存分配时必须判断返回值是否为NULL;
  • 动态内存分配有助于消除程序内部存在的限制;
  • 使用sizeof计算数据类型的长度,可以提高程序的可移植性。
处无为之事,行不言之教;作而弗始,生而弗有,为而弗恃,功成不居!

欢迎关注我的其它发布渠道