C语言学习笔记

堆区空间申请(一)

栈区变量分析

  • 所有程序/软件的运行,都是由操作系统统一调配的,操作系统是程序的运行环境
  • 运行中的多个程序之间,内存是不交叉的
  • 程序结束后,操作系统还要释放其使用的资源,来给其他程序使用
  • 申请的空间种分为五个区域栈区(堆栈区),堆区,全局区,字符常量区,代码区,我们之前讲的这些定义变量、数组都是在内存的栈区存储。
  • 为什么分这么多区域?在实际生活中,这和公司差不多,部门分的细致,工作分发的就有针对性,效率就会高。
  • 由谁申请?
    栈区的特点:内存由系统申请,在变量生命周期结束时由系统释放,也就是说,在程序运行的时候,系统要多个任务,就是检测变量是否该释放了,简单来说,就是cpu要抽时间去执行这部分功能。所以,如果这种变量比较多,不加节制的定义的话,那CPU的额外的工作量就会加大,综合下来,程序的运行效率就会低下。
    堆区的特点:由我们程序员随时申请,由我们自己随时释放。
  • 实际应用中,系统会限制我们可使用的栈区空间大小(默认1M)stack overflow即为爆栈。
    这个大小可以从编译器的属性中修改,但尽量不修改,不够用了又不得不用再去修改。
    如果我们申请的空间,不由操作系统管理,而是我们自己申请与释放,那么就不会占用系统的额外资源了,这样我们就可以申请任意大小的空间了。

malloc函数介绍

  • 功能:在堆区空间中申请指定大小的,连续的,一段空间,并返回该空间的首地址。
    理论上,32位系统最大申请4G,64位系统最大16Tb(由安装内存决定)
  • 函数的原型:void *malloc(size_t size);
  • int *p = (int*)malloc(4);这样的一条语句即为申请一个4字节的int类型的堆区空间,并且定义一个指针变量p指向这个空间的首字节的地址(其中的4当然可以换成sizeof(int)),如果输入的是小数,也会被系统转换为整数,所以还是输入整数
    其实这里的4是int型的,更加标准的写法是4u,但是编译器会自动将有符号整形转换为无符号整型。
  • 头文件:malloc也是一个内建函数,所以头文件要求并没有那么高,但是更加标准的是<stdlib.h><malloc.h>

size_t详解

  • size_t在不同操作系统的软件里代表的被重命名的函数不一样,实测在32位的编译器中size_t == unsigned int,在64位的编译器中size_t == long unsigned int经过输出字节数可以证明(结果分别是4,8)

malloc申请空间的讨论

  • malloc(正常数)时会出现的内存碎片
    在malloc申请了一段指定字节数的空间后,即使后来将其释放,也不一定会被系统再次利用到。例如先申请了20B,后来要申请30B,则会形成内存碎片
  • malloc(0):
    会申请一个可用空间,但是其不可用
  • malloc(极限空间):
    申请的空间超出了内存,会得到返回值NULL,即为0;
    int *p = (int*)malloc(2*1024*1024*1024);(8G,32位程序中)会提示数据类型溢出;
    int *p = 2*1024*1024*1024 - 1甚至会提示两个错误,因为再乘法运算之后,数据类型就已溢出,再-1当然还在继续溢出;
    但是如果修改数据类型int *p = (int*)malloc(2u*1024u*1024u*1024u)就不会再有警告了,因为无符号的整形的范围是0~2^32-1。所以经常会在申请堆区空间之后进行一个if的判断,是否NULL == p,然后提示操作人员能否继续操作。

malloc空间赋值###

  • 强制类型转换:
    (类型*),malloc就是返回的void*,所以我们要转换成我们想要的类型,操作
  • 申请的空间不能初始化,不能像基本数据类型一样直接赋值,例如int a = 1,如果直接输出,会得到一个随机数,要是想给*p赋值,我们就要用*p = 0类似的语句来进行赋值
    那如果我们申请的堆区空间是这样的int *p = (int*)malloc(40),其实我们就是申请了一个数组,赋值方式、数值运算与数组完全一致。
  • 当然我们使用循环,对于数组的赋值并不是很方便,所以这里介绍一个新的函数memset
    memset的意义是将一段字节内的所有数值赋值为0。memset用法:int *p = (int*)malloc(40);memset(p, 0, 40);
    要点:切记memset是对内存赋值,memset(p,1,40);的结果是每一个4字节的数据,例如p[0],p[5]的数据全都是0000 0001 0000 0001 0000 0001 0000 0001即为16843009‬(10),所以这个函数经常用在将整个空间全部赋值为0。memset的头文件是<string.h>或者<memory.h>(一个int类型是4个字节,一个字节是8位二进制数)
  • 对于空间内数据的操作还是使用*p,这个是没有什么特殊的。

malloc注意点###

  • 不要申请的空间不够用,比如要申请4字节给int类型用,千万别申请三个,这样直接导致了越界,并且导致无法释放
  • 注意边界,这个有点像数组,例如int *p = (int*)malloc(4);*(p+1) = 12这样显然是越界操作,在编译时不会报错,但是运行时会崩溃
  • 一个指针指向了一块堆区空间,千万不要再指向另一块,因为相当于重新赋值,会导致内存丢失、造成内存泄露,且形成内存碎片,如果是在循环中会无限占用内存,导致死机

C语言学习笔记——堆区空间申请(一)相关推荐

  1. C++程序设计语言学习笔记:名字空间

    1.名字空间(namespace)的概念用来直接表示本属一体的一组特性,例如库代码.名字空间的成员都位于相同的作用域中,无需特殊符号即可相互访问,而从名字空间外访问它们就需要显式符号. 2.显式限定: ...

  2. 梓益C语言学习笔记之链表&动态内存&文件

    梓益C语言学习笔记之链表&动态内存&文件 一.定义: 链表是一种物理存储上非连续,通过指针链接次序,实现的一种线性存储结构. 二.特点: 链表由一系列节点(链表中每一个元素称为节点)组 ...

  3. 嵌入式C语言——学习笔记

    嵌入式C语言--学习笔记 计算机程序语言的学习思路? GCC的使用及其常用选项介绍 gcc概述 C语言编译过程 C语言常见的错误 预处理的使用 宏展开下的 #.## C语言常用关键字及运算符操作 关键 ...

  4. 【Go语言 · 学习笔记】

    文章目录 Go语言 · 学习笔记 一.Go包管理 1. 什么是Go语言中的包 2. 包的命名 3. main包 4. 导入包 5. 远程包导入 6. 命名导入 7. 包的init函数 二.Go开发工具 ...

  5. (一)Go语言学习笔记

    Go语言学习笔记 1 前言 2 写Go语言需要注意的地方 2.1 Go语言编译执行和直接run的区别 2.2 Go语言的特点 2.3 Linux下配置Go环境变量 2.4 随记 3 go_code 3 ...

  6. C语言学习笔记10-指针(动态内存分配malloc/calloc、realloc、释放free,可变数组实现;Tips:返回指针的函数使用本地变量有风险!;最后:函数指针)

    C语言:指针 1. 指针:保存地址的变量 *p (pointer) ,这种变量的值是内存的地址.   取地址符& 只用于获取变量(有地址的东西)的地址:scanf函数-取地址符   地址的大小 ...

  7. C语言学习笔记08-函数、变量作用域{}

    C语言自定义函数 函数 / 方法(面向对象语言),将功能重复的代码段(原始的方式是cv)提取抽象出main方法外,将其放入一个新的函数中,从而在main中只需要调用该函数就可完成一项复杂的工作,代码会 ...

  8. 史上最全C语言学习笔记

    最全C语言学习笔记 学习目标 学习编程最主要目标 分析问题的能力.构造算法的能力.编程的能力. 调试程序的能力. 学习方法手段 如何操作? 解题思路:重点要放在解题的思路上 一开始就要学会看懂程序,编 ...

  9. 梓益C语言学习笔记之指针

    梓益C语言学习笔记之指针 一.32位平台下,地址是32位,所以指针变量占32位,共4个字节 二.内存单元的地址即为指针,存放指针的变量称为指针变量,故:"指针"是指地址,是常量,& ...

最新文章

  1. 科软2020计算机科学与技术,2020新高考 报考计算机类专业怎么选科
  2. 确认过眼神(*╹▽╹*),这就是大家想要的BCH
  3. 进程线程006 Windows线程切换-线程优先级
  4. Realtime Ray Tracing RenderMan Point Cloud
  5. 全绿色版影视电影小程序源码-提供苹果CMS接口
  6. 三款最安全的Linux操作系统(适合从事网络安全工作者使用)
  7. C++ 运算符重载的原理
  8. ros之service通讯
  9. 进军生物计算!百度发布飞桨螺旋桨PaddleHelix
  10. 最优秀的微信小程序UI组件库
  11. Python 爬虫 scrapy 反 反爬虫策略
  12. html查看器查看图片,jQuery功能强大的图片查看器插件
  13. 计算机cpu的字母,电脑处理器后面的字母你认识几个?不认识跟我来学学(intel篇)...
  14. RIA系列技术讲座(1)——在RIA世界里混个脸熟
  15. AD8066ARZ介绍
  16. python计算学生平均年龄_不能理解平均年龄的计算
  17. CCF-CSP题解 201912-3化学方程式【字符串处理+模拟】
  18. Android项目:基于Android图书馆借阅系统app毕业设计(计算机毕业设计)
  19. 一位资深机械设计师的工作经验和感悟,受益匪浅!
  20. Matlab:实现“光学拍”仿真

热门文章

  1. 2021年全国大学生电子设计竞赛F题中数字识别这一技术分支实践与学习笔记
  2. 前端 获取 扫码枪等扫码设备输入内容:2种方式
  3. 中软国际南京分公司发offer想问问到底咋样,能不能去
  4. uAvionix 获得 FAA 批准进行 C 波段测试,并继续在几个新地点推出 SkyLine C2
  5. CR总结--java函数CR
  6. Linux系统及应用复习题
  7. 河南省多校联盟二-F 线段树+矩阵
  8. 电子漫画系列更新11张美图,共计58张,收藏收藏!
  9. 小a和小b一起玩一个游戏,两个人一起抛掷一枚硬币,正面为H,反面为T。两个人把抛到的结果写成一个序列。如果出现HHT则小a获胜,游戏结束。如果HTT出现则小b获胜。问a获胜的概率?
  10. 经营分析师如何进一步提升自己的境界