C语言学习笔记——堆区空间申请(一)
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语言学习笔记——堆区空间申请(一)相关推荐
- C++程序设计语言学习笔记:名字空间
1.名字空间(namespace)的概念用来直接表示本属一体的一组特性,例如库代码.名字空间的成员都位于相同的作用域中,无需特殊符号即可相互访问,而从名字空间外访问它们就需要显式符号. 2.显式限定: ...
- 梓益C语言学习笔记之链表&动态内存&文件
梓益C语言学习笔记之链表&动态内存&文件 一.定义: 链表是一种物理存储上非连续,通过指针链接次序,实现的一种线性存储结构. 二.特点: 链表由一系列节点(链表中每一个元素称为节点)组 ...
- 嵌入式C语言——学习笔记
嵌入式C语言--学习笔记 计算机程序语言的学习思路? GCC的使用及其常用选项介绍 gcc概述 C语言编译过程 C语言常见的错误 预处理的使用 宏展开下的 #.## C语言常用关键字及运算符操作 关键 ...
- 【Go语言 · 学习笔记】
文章目录 Go语言 · 学习笔记 一.Go包管理 1. 什么是Go语言中的包 2. 包的命名 3. main包 4. 导入包 5. 远程包导入 6. 命名导入 7. 包的init函数 二.Go开发工具 ...
- (一)Go语言学习笔记
Go语言学习笔记 1 前言 2 写Go语言需要注意的地方 2.1 Go语言编译执行和直接run的区别 2.2 Go语言的特点 2.3 Linux下配置Go环境变量 2.4 随记 3 go_code 3 ...
- C语言学习笔记10-指针(动态内存分配malloc/calloc、realloc、释放free,可变数组实现;Tips:返回指针的函数使用本地变量有风险!;最后:函数指针)
C语言:指针 1. 指针:保存地址的变量 *p (pointer) ,这种变量的值是内存的地址. 取地址符& 只用于获取变量(有地址的东西)的地址:scanf函数-取地址符 地址的大小 ...
- C语言学习笔记08-函数、变量作用域{}
C语言自定义函数 函数 / 方法(面向对象语言),将功能重复的代码段(原始的方式是cv)提取抽象出main方法外,将其放入一个新的函数中,从而在main中只需要调用该函数就可完成一项复杂的工作,代码会 ...
- 史上最全C语言学习笔记
最全C语言学习笔记 学习目标 学习编程最主要目标 分析问题的能力.构造算法的能力.编程的能力. 调试程序的能力. 学习方法手段 如何操作? 解题思路:重点要放在解题的思路上 一开始就要学会看懂程序,编 ...
- 梓益C语言学习笔记之指针
梓益C语言学习笔记之指针 一.32位平台下,地址是32位,所以指针变量占32位,共4个字节 二.内存单元的地址即为指针,存放指针的变量称为指针变量,故:"指针"是指地址,是常量,& ...
最新文章
- 科软2020计算机科学与技术,2020新高考 报考计算机类专业怎么选科
- 确认过眼神(*╹▽╹*),这就是大家想要的BCH
- 进程线程006 Windows线程切换-线程优先级
- Realtime Ray Tracing RenderMan Point Cloud
- 全绿色版影视电影小程序源码-提供苹果CMS接口
- 三款最安全的Linux操作系统(适合从事网络安全工作者使用)
- C++ 运算符重载的原理
- ros之service通讯
- 进军生物计算!百度发布飞桨螺旋桨PaddleHelix
- 最优秀的微信小程序UI组件库
- Python 爬虫 scrapy 反 反爬虫策略
- html查看器查看图片,jQuery功能强大的图片查看器插件
- 计算机cpu的字母,电脑处理器后面的字母你认识几个?不认识跟我来学学(intel篇)...
- RIA系列技术讲座(1)——在RIA世界里混个脸熟
- AD8066ARZ介绍
- python计算学生平均年龄_不能理解平均年龄的计算
- CCF-CSP题解 201912-3化学方程式【字符串处理+模拟】
- Android项目:基于Android图书馆借阅系统app毕业设计(计算机毕业设计)
- 一位资深机械设计师的工作经验和感悟,受益匪浅!
- Matlab:实现“光学拍”仿真
热门文章
- 2021年全国大学生电子设计竞赛F题中数字识别这一技术分支实践与学习笔记
- 前端 获取 扫码枪等扫码设备输入内容:2种方式
- 中软国际南京分公司发offer想问问到底咋样,能不能去
- uAvionix 获得 FAA 批准进行 C 波段测试,并继续在几个新地点推出 SkyLine C2
- CR总结--java函数CR
- Linux系统及应用复习题
- 河南省多校联盟二-F 线段树+矩阵
- 电子漫画系列更新11张美图,共计58张,收藏收藏!
- 小a和小b一起玩一个游戏,两个人一起抛掷一枚硬币,正面为H,反面为T。两个人把抛到的结果写成一个序列。如果出现HHT则小a获胜,游戏结束。如果HTT出现则小b获胜。问a获胜的概率?
- 经营分析师如何进一步提升自己的境界