数组在内存中时存储在连续的位置上,当声明一个数组的时候,编译器就会在内存中分配它所需要的空间,但是有时候还需要使用动态内存为数组分配空间。

  比如现在要同统计一个班级学生的成绩,可以申请一个固定大小的数组,但是班级学生的人数时会变动的,当这个固定大小的数组设置的太小时,有可能不能完全放下所有学生的数据,当这个数组设置的太大时,不一定每次每次都能用到这么大的空间。导致系统空间的浪费。

  为了使程序更加灵活,同时更加有效的利用内存空间,通常使用动态内存分配来解决这个问题,C库函数里面提供了两个函数mallocfree,一个用来申请内存,一个用来释放内存。这两个函数都在头文件 stdlib.h 中包含。

  void *__cdecl malloc(size_t _Size);void __cdecl free(void *_Memory);

  malloc函数用来申请内存空间,它的参数就是需要分配的内存字节数,如果内存中的空间可以满足这个需求,malloc 就会返回一个指向分配的内存块起始位置的指针。如果内存中的空间无法满足这个需求,malloc 就会返回一个NULL指针。

  malloc所分配嗯是一块连续的内存。如果请求它分配100个字节的内存,那么这100个字节在内存中就是连续的,它并不会将不同块的内存组合成一块内存来分配。

  当使用完内存块之后,必须使用free函数来释放所分配的内存,free 的参数要么是NULL,要么是malloc函数返回的地址指针值。

  下面通过一个简单的例子来演示一下动态内存的使用。

#include <stdio.h>
#include <stdlib.h>int main(int argc, char** argv)
{int *pi;int i,j;printf("请输入需要分配的内存大小:");scanf("%d",&i);pi = malloc(i);if(pi == NULL){printf("内存分配失败!\n");exit(1); }printf("\r\n内存分配成功:");for(j=0;j<i;j++){pi[j] = j;}for(j=0;j<i;j++){printf("%d ",pi[j]);}printf("\r\n\r\n释放内存!\r\n");free(pi);return 0;
}

  首先通过键盘输入一个数字,用来确定需要分配的内存大小,然后使用 malloc 函数动态分配内存,内存分配成功后,给内存中填充数字然后将数字打印出来,数字打印完成后就不在需要内存了,此时调用 free 函数释放刚才分配的内存。

  程序运行结果如下:

  如果内存使用完成之后没有及时释放,那么此块内存在系统中就会一直存在,并且也不能被重新使用,这样随着程序的运行系统中的内存就会越来越少,最后导致系统奔溃。这个过程有一个专业名称叫做内存泄露

  使用动态分配内存可以有效的利用内存空间,但是它也不是没有缺点,动态分配内存会产生内存碎片

  那么为什么会产生内存碎片呢,这里使用一个简单的例子来说明一下。比如在此时系统动态申请了两次内存分配,每个内存的大小都是10。内存分配的情况如下:

  当第一个内存空间使用完成后,代码释放了内存。这样在内存中就有了10个空闲的位置。

  此时又有程序申请了8个内存,这时系统就会在刚才释放的空间中重新分配8个给当前程序。

  这时候在内存中就会留出来2个空闲的内存,如果刚好有程序需要2个大小的内存,那么这块内存就会被利用上,但是由于2个内存太小了,很难有机会在被利用上,那么这两个空间的内存就会永远的被留在这里。当程序运行时不停的申请释放内存,而每次申请内存时,内存空间必须是连续的,那么这些小的空闲内存就不会被使用到,就产生了内存碎片。程序运行的越久,产生的内存碎片就会越多。

  当电脑使用比较久的时候,对硬盘进行碎片整理,就会看到硬盘的内存的存储情况。从图中就可以明确的看出,在内存中未使用的的小块空闲内存占了很大一部分。

C语言学习笔记---动态内存分配相关推荐

  1. c语言的四个函数,C语言学习之动态内存分配的四个函数

    前面中我们了解到: int n; int arr[n]; 这样定义数组是不可取的,不能用此方法给数组分配动态内存,那怎么样才能实现这种可能呢? 接下来我将关于动态内存的知识做以下总结. 有关动态内存的 ...

  2. c语言链表内存分配失败,链表的C语言实现之动态内存分配

    链表的C语言实现之动态内存分配 來源:互聯網  2008-06-01 02:05:07  評論 一.为什么用动态内存分配 但我们未学习链表的时候,假如要存储数量比较多的同类型或同结构的数据的时候,总是 ...

  3. c语言链表动态分配内存,链表的C语言实现(含动态内存分配)

    转自:http://blog.csdn.net/21aspnet/article/details/146968 链表的C语言实现(含动态内存分配) 上 链表的C语言实现之动态内存分配 一.为什么用动态 ...

  4. C语言中的动态内存分配

    大家好,今天简单讲一讲C语言中的动态内存分配. 补充:C程序中的内存块. 在C程序中,通常将内存划分为以下六个区域: (1)内核区域.这块区域是操作系统的,用户不能使用. (2)栈区.主要用于存放运行 ...

  5. c语言 malloc_C语言快速入门——动态内存分配

    在前面一系列的字符串操作中,我们都是先定义一个固定大小的字符数组,然后根据所需,或拷贝.或连接.或格式化来为这个数组提供内容.固定大小的数组意味着在程序运行期间,数组所占用的内存是确定的(即划分了固定 ...

  6. C++和C语言中的动态内存分配的区别

    在C语言和C++中都会用到动态内存的申请分配的问题,两者之间申请动态内存分配还是区别的. 在C++中的动态内存的分配 1.C++通过new关键字进行动态内存的分配.new关键字是C++内置的一个关键字 ...

  7. C语言学习笔记--动态库和静态库的使用

    link 1.C语言中的链接器 (1)每个 C 语言源文件被编译后生成目标文件,这些目标文件最终要被链接在一起生成可执行文件. (2)链接器的主要作用是把各个模块之间相互引用的部分处理好,使得各个模块 ...

  8. C语言,为什么动态内存分配申请后,还要再释放?

    比如main函数里有一句 malloc(), 后面没有free() 1.那么当main结束后,动态分配的内存不会随之释放么? 2.如果程序结束能自动释放,那么还加上free(),是出于什么考虑? 1. ...

  9. C语言学习笔记:内存的五大分区

    在C语言中,进程可在内存中分别存入五大分区: 1.text:也称为代码段,其中主要用于存放二进制指令.常量.被const修饰过的初始化过的全                      局变量.静态局部 ...

最新文章

  1. puppet自动化运维之puppet的资源基础知识
  2. json_decode
  3. 什么是对象的消息_SpringBoot+RabbitMQ方式收发消息,一文带你体验
  4. oracle的parse是什么意思,Oracle性能测量体系(Parse Time)
  5. boost::stable_vector简单解析
  6. 机械制造工艺基础_机械制造工艺基础知识,錾削与锯削加工工艺
  7. java中Arrays类和Math类常用API简介
  8. HTML5概述、标签
  9. erlang observer工具
  10. MATLAB画简单函数图形
  11. Arduino使用蓝牙通信模块
  12. python操作个人简历,python爬虫开发工程师应届生个人简历模板(Word可以直接使用)...
  13. 什么是单臂路由?单臂路由的优缺点?如何配置单臂路由?
  14. 【centos】快速截图设置
  15. FFMPEG使用摄像头录像并编码
  16. 解决 login.live.com onedrive.live.com 等微软国外网站打不开问题
  17. 解决电脑右键菜单反应慢问题
  18. 个人永久性免费-Excel催化剂功能第85波-灵活便捷的批量发送短信功能(使用腾讯云接口)...
  19. 利息计算器V3.0感悟
  20. python基础编程(Ⅲ)

热门文章

  1. asp.net中使用#include语法将文件添加到页面
  2. [前缀和][dp] Jzoj P5873 小p的属性
  3. 杨辉三角形函数 JavaScript Generator 实现
  4. Tao 1.2.0图形框架发布
  5. RTP 时间戳的处理
  6. Spring Boot教程(十六):Spring Boot集成shiro
  7. web端兼容性测试相关知识
  8. deldir | 生成泰森多边形的一段R语言代码
  9. python连接池框架_Python中的连接池是非常重要的!神级程序员详解!
  10. python怎么实现黑客攻击英国_注意!你的隐私就是这样被黑客获取的