1. 动态分配内存的概述

    • 在数组一章中,介绍过数组的长度是预先定义好的,在整个程序中固定不变,但是在实际的编程中,往往会发生这种情况,即所需内存空间取决于实际输入的数据,而无法预先确定。为了解决上述问题,c语言提供了一些内存管理函数,这些内存管理函数可以按需要动态的分配内存空间,也可把不再使用的空间回收再次利用

  2. 静态分配、动态分配

    • 静态分配

      • 在程序编译或运行过程中,按事先规定大小分配内存空间的分配方式 int a[10]

      • 必须事先知道所需空间的大小

      • 分配在栈区或全局变量区,一般以数组的形式

      • 按计划分配

    • 动态分配

      • 在程序运行过程中,根据需要大小自由分配所需空间

      • 按需分配

      • 分配在堆区,一般使用特定的函数进行分配

  3. 动态分配函数

    • 所需头文件 include 'stdlib.h'

    • malloc函数

      • 函数原型: void*malloc(unsigned int size)

      • 功能说明

        • 在内存的动态存储区(堆区)中分配一块长度为size字节的连续区域,用来存放类型说明指定的类型。函数原型返回 void* 指针,使用时必须做相应的强制类型转换;分配的内存空间内容不确定,一般使用memset初始化.

      • 返回值: 分配空间的起始地址(分配成功) NULL(分配失败)

      • 注意:

        • 在调用malloc之后,一定要判断一下,是否申请内存成功

        • 如果多次malloc申请的内存,第一次和第二次申请的内存不一定是连续的

      • 举例

        • include 'stdlib.h'

        • include 'stdio.h'

        • include 'string.h'

        • int main(){

        • int count,*array,n;

        • printf("请输入您要申请的数组元素个数\n");

        • scanf("%d",&n);

        • array = (int*)malloc(n *sizeof(int));

        • if (array = NULL)

        • {

        • printf("申请内存失败\n");

        • return 0;

        • }

        • memset(array,0,n*sizeof(int));

        • for(count=0;count<n;count++)

        • {

        • array[count] =count;

        • }

        • for(count = 0;count<n;count++)

        • {

        • printf("%d\n",array[count]);

        • }

        • free(array); //释放array指向的内存

        • return 0;

        • }

    • free 函数(释放内存函数)

      • 函数定义 void free(void*ptr)

      • 函数说明 :free函数释放ptr指向的内存

      • 注意 ptr指向的内存必须是 malloc calloc relloc 动态申请的内存

      • 注意

        • free后,因为没有给p赋值,所以p还是指向原先动态申请的内存.

        • 一块动态申请的内存只能free一次,不能多次free

    • calloc函数

      • 函数定义 void *calloc(size_t,nmemb,size_t,size);

      • size_t 实际是无符号整型,它是在头文件中,用typedef定义出来的

      • 函数的功能:在内存的堆中,申请nmemb块,每块的大小为size个字节的连续区域

      • 函数的返回值

        • 返回 申请的内存的首地址(申请成功)

        • 返回NULL(申请失败)

      • 注意: malloc和calloc 函数都是用来申请内存的

      • 区别:

        • 函数的名字不一样

        • 参数的个数不一样

        • malloc申请的内存,内存由存放的内容是随机的,不确定的,而calloc函数申请的内存中的内容为0

      • 调用方法

        • char*p = (char *)calloc(3,100)

        • 在堆中申请了3块,每块大小为100个字节,即300个字节连续的区域

    • relloc 函数 (重新申请内存)

      • 咱们调用的malloc 和calloc函数 单次申请的内存是连续的,两次申请的两块内存不一样连续,有些时候有这种需求,即我先用malloc或者calloc申请了一块内存,我还想再原内存上申请,或者我开始时候使用malloc或者calloc申请了一块内存,我想释放后边的一部分内存,为了解决这个问题,发明了relloc函数

      • 函数的定义: void*relloc(void *s,unsigned int newsize)

      • 函数的功能:

        • 再原先s指向的内存基础上重新 申请内存,新的内存的大小为 new_size 如果原先内存后面有足够大的空间,就追加,如果后边的内存不够用,则relloc 函数会,找一个newsize 个字节大小的内存申请,将原先内存中的内容拷贝过来,然后存进新内存的地址

      • 如果newsize比原先的内存小,则释放原先内存的后面的存储空间。只留下前面的newsize返回值:新申请的内存的首地址

      • 举例

        • char *p;

        • p = (char* )malloc (100);

        • //咱们想在100个字节后面追加50个字节

        • p = (char *)relloc (p,150);//p指向的内存的新的大小为150个字节

        • char *p;

        • p = (char *)malloc(100);

        • //咱们想重新申请内存,新的大小为50个字节

        • p = (char*)relloc(p,50);// p指向的内存的新的大小为50个字节,100个字节后的50个字节被释放了

    • 注意: malloc calloc relloc 动态申请的内存 ,只有再free或程序结束的时候才释放

    • 内存泄漏

      • 内存泄漏的概念:

        • 申请的内存,首地址丢了,找不了,再也没法使用了,也没法释放了,这块内存就被泄漏了.

      • 举例

        • int main(){

        • char*p;

        • p = (char*)malloc(100);

        • // 接下来,可以用p指向的内存了

        • p = "hello world";// p 指向别的地方了

        • //从此以后,再也找不到你申请的100个字节了,则动态申请的100个字节就被泄漏了

        • }

        • void fun(){

        • char *p;

        • p = (char*) malloc(100);

        • // 接下来,可以用p指向的内存了

        • }

        • int main(){

        • fun();

        • fun();

        • return 0;

        • //加个free(p); 就解决了内存泄漏

        • // 每调用一次fun 泄漏100个字节

        • }

        • 解决方法2

        • char*fun(){

          • char *p;

          • p = (char*) malloc(100);

          • // 接下来,可以用p指向的内存了

          • return p;

          • }

          • int main(){

          • char *q;

          • q=fun(); //可以通过q使用,动态申请的100个字节的内存了

          • //记得释放

          • free(p);

          • // 每调用一次fun 泄漏100个字节

          • }

    • 总结:申请的内存,一定不要把首地址给丢了,在不用的时候一定要释放内存

C语言动态内存的更多相关文章

  1. C语言动态内存的申请和释放

    什么是动态内存的申请和释放? 当程序运行到需要一个动态分配的变量时,必须向系统申请取得堆中的一块所需大小的存储空间,用于存储该变量.当不再使用该变量时,也就是它的生命结束时,要显式释放它所占用的存储空 ...

  2. C语言动态内存管理

    1-概述 动态存储管理的基本问题是:系统如何按请求分配内存,如何回收内存再利用.提出请求的用户可能是系统的一个作业,也可能是程序中的一个变量. 空闲块 未曾分配的地址连续的内存区称为“空闲块”. 占用 ...

  3. C语言动态内存分配

    考虑下面三段代码: 片段1 void GetMemory(char *p) { p = (); } void Test(void) { char *str = NULL; GetMemory(str) ...

  4. C语言和内存

    1.程序的运行 对cpu来说,内存只是一个存放指令和数据的地方,具体的运算在cpu内完成. 1.寄存器(Register) 是CPU内部非常小.非常快速的存储部件,它的容量很有限,对于32位的CPU, ...

  5. C++中对C的扩展学习新增语法——动态内存管理

    1.C语言动态内存管理的缺点: 1.malloc对象的大小需要自己计算. 2.需要手动转换指针类型. 3.C++的对象不适合使用malloc和free. 2.C++中new/delete基本使用: 3 ...

  6. C语言通过函数参数不能带出动态内存的例子。

    实验结论:通过函数参数不能带出动态内存,函数参数虽然为指针,其实是在函数内部的临时变量,只是该指针的初始值是通过调用函数赋值的.C语言函数参数都是传值的. #include <stdio.h&g ...

  7. 数据结构基础(1)--数组C语言实现--动态内存分配

    数据结构基础(1)--数组C语言实现--动态内存分配 基本思想:数组是最常用的数据结构,在内存中连续存储,可以静态初始化(int a[2]={1,2}),可以动态初始化 malloc(). 难点就是数 ...

  8. C语言中动态内存的分配(malloc,realloc)

    动态内存分配:根据需要随时开辟,随时释放的内存分配方式.分配时机和释放时机完全由程序员决定,由于没有数据声明,这部分空间没有名字.无法像使用变量或数组那样通过变量名或数组名引用其中的数据,只能通过指针 ...

  9. C语言学习笔记--动态内存分配

    1. 动态内存分配的意义 (1)C 语言中的一切操作都是基于内存的. (2)变量和数组都是内存的别名. ①内存分配由编译器在编译期间决定 ②定义数组的时候必须指定数组长度 ③数组长度是在编译期就必须确 ...

随机推荐

  1. markdown-it + highlight.js简易实现

    markdown-it 官方demo markdown-it 文档 1.配置highlightjs,针对markdown中各种语言高亮,针对对应的标签 pre code 里面的样式 -- index. ...

  2. 《DL/T 976-2017 带电作业用工具、装置和设备预防性试验规程》中的样品名称及试验项目

  3. 配置 IO 时要记得换 Page

    配置 IO 时要记得换 Page 在配置某些芯片时,配置 IO 时要记得换页,不然不生效. 注意查看 IO 的相关规格书说明,而且每个厂商是不一样的.

  4. 阿里云IPv6 DDoS防御被工信部认定为“网络安全技术应用试点示范项目”

    ​​近日,阿里云数据中心骨干网IPv6 DDoS网络安全防御被工业和信息化部认定为“网络安全技术应用试点示范项目”,本次评选由工业和信息部网络安全管理局发起,从实用性.创新性.先进性.可推广性等维度展 ...

  5. @codechef - MGCH3D@ 3D Queries

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 在三维空间内有 N 个不同的点,请计算下面式子的值 Q 次: \ ...

  6. uva 11916 Emoogle Grid (BSGS)

    UVA 11916 BSGS的一道简单题,不过中间卡了一下没有及时取模,其他这里的100000007是素数,所以不用加上拓展就能做了. 代码如下: #include <cstdio> #i ...

  7. 使用git和sourcetree提交代码的一些问题

    今天遇到的几个坑算是解决了1.开始不能用指令提交,可以执行git add命令前添加gitdir=$(git rev-parse --git-dir); scp -p -P 29418 wangtao1 ...

  8. js实现圆形的碰撞检测

    文章地址:https://www.cnblogs.com/sandraryan/ 碰撞检测这个东西写小游戏挺有用der~~~ 注释写的还挺全,所以就不多说了,看注释 这是页面结构.wrap存放生成的小 ...

  9. Linux 使用 Speedtest 测试网速

    Speedtest的linux客户端是用python写的一个安装包 安装python包管理器pip yum -y install python-pip 如果提示No package python-pi ...

  10. C#循环语句练习(三)

    for循环拥有两类:一.穷举:把所有可能的情况都走一遍,使用if条件筛选出来满足条件的情况. (1).羽毛球拍15元,球3元,水2元.200元每种至少一个,有多少可能. (2).百鸡百钱:公鸡2文钱一 ...