什么时动态内存分配

一般我们写程序都是在栈区分配空间,如果我们想根据需求想随时存放随时释放数据,堆区可以实现根据需求想系统申请所需大小的空间。

建立内存的动态分配

内存的动态分配是通过系统提供的函数来实现的,主要有malloc,calloc,free,realloc这四个函数,都需要引用stdlib.h或者malloc.h文件.
在malloc,calloc,realloc函数向堆区申请空间之后,处理完数据需要释放空间。

用malloc函数开辟动态存储区

int main()
{int n=5;int *ip =NULL;ip=(int*)malloc(sizeof(int)*n)//表示向堆区申请n个int型的字节if(ip==NULL)exit(1);     //注意:在向堆区申请完空间之后一定要对指针进行判空//处理数据free(ip);   //处理完数据对空间进行释放ip=NULL;    //释放完堆区空间对指针置空

注意:

  1. 在申请空间时,指针是什么类型申请的空间就要强转为什么类型。
  2. 函数malloc申请的是连续指定的空间
  3. 函数malloc在申请空间之后并不进行初始化。

用calloc函数开辟动态存储区

int main()
{int n=5;int *ip =NULL;ip=(int*)calloc(n,sizeof(int))//表示向堆区申请n个int型的字节if(ip==NULL)exit(1);     //注意:在向堆区申请完空间之后一定要对指针进行判空//处理数据free(ip);   //处理完数据对空间进行释放ip=NULL;

注意:

  1. 函数calloc在申请空间之后会将空间内初始化为0。
  2. 分配成功后,会返回指向分配内存块的手字节指针,它为任何类型适当对齐

用realloc函数重新分配动态存储区

int main()
{int n=5;int *ip =NULL;ip=(int*)malloc(sizeof(int)*n)//表示向堆区申请n个int型的字节if(ip==NULL)exit(1); //如果发现申请的20个字节空间不够用realloc函数申请重新分配ip=(*int)realloc(ip,sizeof(int)*10);//表示将空间扩大到40字节

注意:

  1. 函数realloc重新分配给定的内存区域,它必须是之前分配过的空间,而且仍然没有被释放的空间,否则结果未定义。
  2. 函数realloc可以扩大或者缩小已分配的空间,若内存可以直接扩展将直接阔展,不能直接扩展将复制原来空间的内容在堆区重新找合适的空间存放数据,指针ip指向重新分配的空间。若堆区没有空间,则返回空指针。

用free函数释放开辟动态存储区

注意:

  1. 任何函数在申请空间之后都要对指针进行判空,看空间是否申请成功。
  2. free函数释放的是系统分配的堆区空间,指针仍旧是指向堆区的,这时指针是失效指针。所以在释放空间之后,一定要将指针置空,防止发生错误。
  3. free函数释放空间时,申请多少释放多少,不存在释放一般的情况。

动态内存管理与结构体:

结构体变量和内置类型都有局部,全局,动态生存期
以下程序仅说明问题:

struct student
{char s_name[20];int age;float score;
};                  //设计的结构体;
struct student studa;    //全局变量,未初始化时成员值都是0
int main()
{struct student studa;//局部变量,未初始化时成员值都是随机值;struct student *p1=NULL;p1=(struct student *)malloc(sizeof(struct student));//表示申请12个字节struct student *p2=(struct student *)malloc(sizeof(*p2));//这种是对的,表示申请p2指向的内容大小个字节struct student *p3=(struct student *)malloc(sizeof(p3));//不对,p3是指针类型,只能申请4个字节大小。//处理数据free(sp1);free(sp2);free(sp3);

柔性指针:在结构体中数组的大小声明为0,或者不给出大小,称之为柔性数组。
柔性数组的定义:

struct node
{int num;int size;char data[]; //char data[0];//在结构体中数组的大小声明为0,或者不给出大小。
}

注意:

  1. 全局数组和局部数不能这样定义,而且定义柔性数组时,必须定义在结构体最后一个元素。
  2. 柔性数组不占用结构体的空间,它只是一个偏移量

柔性数组的申请方式:

struct node
{int num;int size;char data[]; //char data[0];
}
struct node* sp = nullptr;
sp = (node*)malloc(sizeof(node) + 100); //表示申请了108个字节,两个int型是8字节,柔性数组申请了100字节

若将柔性数组换成指针,则申请方式:

struct node
{int num;int size;char *data;
}
node* sp = nullptr;
sp = (node*)malloc(sizeof(node));//表示向堆区申请了12字节的空间
sp->size = 100;
sp->num = 12;
sp->data = (char*)malloc(sizeof(char) * 100);//指针成员再次向堆区申请100个字节的空间

注意:

  1. 柔性数组只需要释放一次即可,指针方式需要释放两次。
  2. 柔性数组即使在赋值后,计算结构体大小还是不能算柔性数组,因为在计算机在编译链接时就已经计算出了结构体大小,编译链接时,柔性数组还没有赋值。

堆区和栈区的区别:

  • 管理方式:栈由系统自动管理;堆由程序员控制,使用方便,但易产生内存泄露。
  • 生长方向:栈向低地址扩展,是连续的内存区域,堆向高地址扩展, 是不连续的内存区域。
  • 空间大小:栈顶地址和栈的最大容量由系统预先规定(通常默认1M或10M),堆的大小则受限于计算机系统中有效的虚拟内存,32位Linux系统中堆内存可达2.9G空间。
  • 存储内容:栈中储存主函数、被调用函数等,被调函数使用完成后先出栈,整个程序完成后主函数出栈,堆通常在头部用一个字节存放其大小,堆用 于存储生存期与函数调用无关的数据,具体内容由程序员安排。
  • 分配方式:栈可静态分配或动态分配。静态分配由编译器完成,动态分配由alloca 函数在栈上申请空间,用完后自动释放不需要调动free函数。堆只能动态分配且手工释放。
  • 分配效率:栈由计算机底层提供支持:分配专门的寄存器存放栈地址,压栈出栈由专门的指令执行,因 此效率较高。堆由函数库提供,机制复杂,效率比栈低得多。
  • 分配后系统响应︰只要栈剩余空间大于所申请空间,系统将为程序提供内存,否则报告异常提示栈溢出。

动态内存分配与柔性数组相关推荐

  1. 【C/C++动态内存 or 柔性数组】——对动态内存分配以及柔性数组的概念进行详细解读(张三 or 李四)

    目录 前言(栈区.堆区.静态区) 动态内存函数 malloc与free calloc与free realloc与free 常见的动态内存错误 经典笔试题(再见张三) 柔性数组 前言(栈区.堆区.静态区 ...

  2. 浅谈C语言动态内存分配及柔性数组

    文章目录 前言 1.动态内存的简单介绍 1.动态内存分配是什么? 2.为什么存在动态内存分配? 3.动态内存分配具体方法 1.动态内存函数 2.动态内存注意事项 2.经典面试题分析 3.C/C++程序 ...

  3. C语言程序设计 | 动态内存管理:动态内存函数介绍,常见的动态内存错误,柔性数组

    动态内存管理目录: 动态内存函数的介绍 常见的动态内存函数的错误 柔性数组 为什么会有动态内存管理呢 我们在日常使用中,创建一个数组,一个变量时都会开辟空间 如: int a; //在栈上开辟一个四字 ...

  4. C语言数组用到的动态内存分配

    动态内存分配 在学习数组的过程中,在输入数组时,原本想过scanf定义数组的大小再输入数组的各值,却报错. 发现原因: 1.定义数组的时必须指定数组长度 2.数组长度是在编译期就必须决定的 所以此时需 ...

  5. 二维数组及其动态内存分配

    一.二维数组的基本概念 1.1 二维数组的内存映像 从内存角度看,二维数组和一维数组一样,在内存中都是连续分布的多个内存单元,并没有本质差别,只是内存的管理方式不一样,如下图所示 一维数组int a[ ...

  6. C/C++——动态内存分配

    动态内存分配,就是指在程序执行的过程中动态地分配或者回收存储空间的分配内存的方法.动态内存分配不像数组等静态内存分配方法那样需要预先分配存储空间,而是由系统根据程序的需要即时分配,且分配的大小就是程序 ...

  7. 【C语言】------ 动态内存分配

    动态内存开辟详解 动态内存分配 什么是动态内存分配? 一.为什么使用动态内存分配呢? 二.动态内存函数 1.malloc和free 2.calloc和realloc 三.常见的动态内存错误 1.对`N ...

  8. c语言动态内存分配数组,【C】动态内存分配

    ## 动态内存分配的意义 C语言中的一切操作都是基于内存的 变量和数组都是内存的别名 内存分配由编译器在编译期间决定 定义数组的时候必须指定数组长度 数组长度是在编译期就必须确定的需求: 程序在运行过 ...

  9. 在c语言中,可以使用动态内存分配技术定义元素个数可变的数组,C语言复制在线考题1精选.doc...

    C语言复制在线考题1精选 窗体顶端 <C语言程序设计208304>综合测试 返回测验列表 大项 1 / 2 - 单项选择题 60.0/ 70.0 分 本大题共35道,每题2分,共计70分, ...

最新文章

  1. spring的@Transactional注解详细用法
  2. linux之用 grep -r 关键字
  3. c++ hashset的用法_C++中set的用法
  4. Mysql索引的创建和使用
  5. 编写java的应用_编写Java应用程序
  6. leetcode 121 python(动态规划)
  7. java 正则regex_Java中的正则表达式– Java Regex示例
  8. Java 去除重复数据的五种方式
  9. Flutter功能 之去除AppBar 阴影
  10. mybatis源码分析(1)-----sqlSessionFactory创建
  11. 不确定性管理,更需要领导力
  12. 2021-1-25计算机快速入门,简单掌握各种技巧
  13. 梅罗对决没了,欧足联的错误?
  14. 开源的网络服务框架:Apache Etch 1.4.0 发布
  15. 四阶魔方java1002四阶魔方java_4x4四阶魔方一看就懂,超简单入门图文教程2:复原中心块...
  16. NLP 实战(10): CSDN 领域榜标签分组更新
  17. 媒体报道 | 《数据安全治理自动化技术框架(DSAG)》白皮书诞生,探索数据安全治理技术“最优解”
  18. 轻量级Qt键盘-实现篇
  19. Android Duplicate class com.xxx found in modules
  20. linux 看芯片信息,Linux查看硬件信息(北桥芯片组、南桥、PCI接口、CPU等)

热门文章

  1. JAVA并发之多线程基础(2)
  2. 铁大Facebook——十天冲刺(5)
  3. 《软件测试经验与教训》之二——测试内容先后顺序
  4. 工作中用不到的技术要不要学?
  5. MongDB-副本集搭建【MongDB系列一】
  6. Session对象失效的客户端解决方法
  7. React学习笔记7:React使用注意事项
  8. Java基础篇:泛型
  9. 一文搞清楚QPS、TPS、并发用户数、吞吐量
  10. 编码编成翔的十八般兵器