深入挖掘C语言 ----动态内存分配

开篇备忘录: "自给自足的光, 永远都不会暗"

目录

  • 1. malloc和free
    • 1.1 malloc
    • 1.2 free
  • 2. calloc和realloc
    • 2.1 calloc
    • 2.2 realloc
  • 3. 总结C/C++中程序内存区域划分


正文开始

1. malloc和free

1.1 malloc

C语言提供了一个动态开辟内存的函数;

void* malloc (size_t size);

这个函数向内存申请一块连续可用的空间, 并返回指向这块空间的指针.

  • 如果内存开辟成功, 则返回一个指向开辟好空间的指针
  • 如果开辟失败, 则返回一个NULL指针, 因此malloc的返回值一定要做检查
  • 返回值的类型是void* ,所以malloc函数并不知道开辟空间的类型, 具体在使用的时候使用者自己来决定
  • 如果参数size为0, malloc的行为标准是未定义的, 取决于编译器

1.2 free

C语言提供了另外一个函数free, 专门是用来做动态内存释放和回收的, 函数原型如下:

void free (void* ptr);

free函数用来释放动态开辟的内存.

  • 如果参数ptr指向的空间不是动态开辟的, 那free函数的行为是未定义的.
  • 如果参数ptr指向的是NULL指针, 则函数什么事都不用做.

malloc 和 free 都声明在stdlib.h 头文件中

int main()
{
	int* ptr = NULL;
	ptr = (int*)malloc(sizeof(int) * 10);
	if (ptr != NULL)
	{
		for (int i = 0; i < 10; i++)
		{
			*(ptr + 1) = 0;
		}
	}
	free(ptr);
	ptr = NULL;
	return 0;
}

2. calloc和realloc

2.1 calloc

C语言还提供了一个函数叫做calloc, calloc函数也用来动态内存分配, 原型如下:

void* calloc (size_t num, size_t size);
  • 函数的功能是为num个大小为size的元素开辟一块空间, 并且把空间的每个字节都初始化为0
  • 与函数malloc的区别在于calloc会返回地址之前把申请的空间的每个字节初始化为0
int main()
{
	int* p = calloc(10, sizeof(int));
	if (p != NULL)
	{
		for (int i = 0; i < 10; i++)
		{
			printf("%d ", *(p + i));
		}
	}
	free(p);
	p = NULL;
	return 0;
}

运行程序:
在这里插入图片描述

所以如果我们对申请的内存空间的内容要求初始化, 那么可以很方便的使用calloch函数来完成任务.

2.2 realloc

  • realloc函数的出现让动态内存管理更加灵活
  • 有时候我们发现过去申请的空间太小了, 有时候我们又会觉得申请的空间过大了, 那为了合理的使用内存, 我们一定会对内存的大小做灵活调整. 那realloc函数就可以做到对动态开辟内存大小的调整

函数原型如下:

void* realloc (void* ptr, size_t size);
  • ptr 是要调整的内存地址
  • size 调整之后新的大小
  • 返回值为调整之后的内存起始位置
  • 这个函数原内存空间大小的基础上, 还会将内存中的数据移动到新的空间
  • realloc 在调整内存空间的时候存在两种情况:
    1. 原有的空间之后有足够大的空间
    1. 原有的空间之后没有足够大的空间

两种情况如下图所示:

在这里插入图片描述

情况1:

要扩展内存就直接原有内存之后直接追加空间, 原来空间的数据不发生变化

情况2:

原有的空间之后没有足够多的空间, 扩展的方法是: 在堆空间上寻找另外一个1合适大小的连续空间来使用, 这样函数返回的就是一个新的内存的地址

由于上述两种情况, realloc函数的使用就要注意一些:

int main()
{
	int* ptr = (int*)malloc(100);
	if (ptr != NULL)
	{
		//业务处理
	}
	else 
	{
		return 1;
	}

	//扩充容量

	//代码1 - 直接将realloc的返回值放到ptr中
	ptr = (int*)realloc(ptr, 100);//(可以吗? , 如果开辟内存失败又会如何?)

	//代码2 - 先将realloc函数的返回值放在p中, 不为NULL,再放在ptr中

	int* p = NULL;
	p = realloc(ptr, 1000);
	if (p != NULL)
	{
		ptr = p;
	}
	//业务处理

	free(ptr);
	free(p);
	ptr = NULL;
	p = NULL;
	return 0;
}

3. 总结C/C++中程序内存区域划分

在这里插入图片描述

C/C++ 程序内存分配的几个区域:

1.栈区(stack): 在执行函数的时候, 函数内局部变量的存储单元都可以在栈上创建,
函数执行结束时这些存储单元自动被释放, 栈内存分配运算内置于处理器的指令集中, 
效率很高, 但是分配的内存容量有限, 栈区主要存放运行函数时而分配的局部变量, 
函数参数, 返回数据, 返回地址等. 这里推荐一本书<<函数栈帧的创建和销毁>>

2.堆区(heap): 一般由程序员分配释放, 若程序员不释放, 程序结束时可能由
OS(操作系统)回收,分配方式类似于链表

3.数据段(静态区): (static) 存放全局变量, 静态数据, 程序结束后由操作系统释放.

4. 代码段: 存放函数体(类成员函数和全局函数)的二进制代码. 

本文内容到此结束, 还望读者点赞关注.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/558248.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Flutter】自动生成图片资源索引插件一:FlutterAssetRefGenerator

介绍 FlutterAssetRefGenerator 插件&#xff1a;windows上 点击生成图片索引按钮后&#xff0c;pubspec.yaml 会出现中文乱码&#xff0c;需要手动改乱码&#xff1b;mac上没问题。 优点&#xff1a;点击图标自动生成。 目录 介绍一、安装二、使用 一、安装 安装FlutterAsset…

VirtualBox Manjaro Linux(kde)虚拟机扩容 增大硬盘存储空间

https://blog.csdn.net/m0_65274357/article/details/131965463 df -h发现/可用空间之后几百M了 文件系统 大小 已用 可用 已用% 挂载点 dev 2.0G 0 2.0G 0% /dev run 2.0G 1.2M 2.0G 1% /run /dev/sda1 40G 37…

车载终端叉车_车载人脸识别ADAS行为识别解决方案

智能车载终端的广泛应用为叉车行业注入了新的活力&#xff0c;提升了驾驶安全和效能。通过采用多种验证技术&#xff0c;如指纹、人脸、扫码和刷卡等&#xff0c;智能车载终端实现了对司机操作权限的验证&#xff0c;在叉车启动时能够自动检测安全带的状态。如果驾驶员未系安全…

OSPF综合大实验

1、R4为ISP&#xff0c;其上只配置IP地址&#xff1b;R4与其他所直连设备间均使用公有IP&#xff1b; 2、R3-R5、R6、R7为MGRE环境&#xff0c;R3为中心站点&#xff1b; 3、整个OSPF环境IP基于172.16.0.0/16划分&#xff1b;除了R12有两个环回&#xff0c;其他路由器均有一个环…

短信登录session-redis

1.流程 1.1 发送验证码 模拟路径 http://127.0.0.1:8080/api/user/code?phone1335566 Request Method:POSTcontroller层 /*** 发送手机验证码*/PostMapping("code")public Result sendCode(RequestParam("phone") String phone, HttpSession session) {…

电机控制专题(二)——Sensorless之扩展反电动势EEMF

文章目录 电机控制专题(二)——Sensorless之扩展反电动势EEMF前言理论推导仿真验证总结参考文献 电机控制专题(二)——Sensorless之扩展反电动势EEMF 前言 总结下电机控制中的扩展反电动势模型。 纯小白&#xff0c;如有不当&#xff0c;轻喷&#xff0c;还请指出。 在得出E…

SD-WAN解决电商企业海外业务网络难题

全球化背景下&#xff0c;众多国内企业都涉及到海外贸易业务&#xff0c;尤其是出海电商得到蓬勃发展。企业做出海电商&#xff0c;需要访问国外网页、社交平台&#xff0c;如亚马逊、TikTok、Facebook、YouTube等与客户沟通互动&#xff0c;SD-WAN的发展正好为解决国际网络访问…

Vue2 移动端(H5)项目封装弹窗组件

前言 因vant-ui的dialog组件没有自定义footer插槽 效果 参数配置 1、代码示例&#xff1a; <t-dialog :visible.sync"show" :title"title" submit"submit"></t-dialog>2、配置参数&#xff08;t-dialog Attributes&#xff09; 参…

吹爆,一款实用的个人IT工具箱

作为一名开发人员&#xff0c;我们在日常工作和学习中常常需要使用一系列小工具&#xff0c;如JSON格式化、JSON转表格、当前时间戳、XML格式化、SQL格式化、密码生成以及UUID生成等。通常情况下&#xff0c;我们会在网上搜索各种在线工具来满足这些需求。 然而&#xff0c;这…

DePIN 赛道黑马,peaq network 如何打造全新 Web3 物联网?

当 Web2 公司仍对用户数据和资料进行“中心化”的收集与控制时&#xff0c;我们虽享受到了物联网技术的便利&#xff0c;却依旧没有逃脱个人数据和价值所有权的剥夺。由此&#xff0c;Web3 技术开始深入物联网世界&#xff0c;智能家居、智能汽车、智能手机都成为重要发力点&am…

冯喜运:4.19黄金,原油市场情绪分析:近期油价可能会回落?

【 黄金消息面解析】&#xff1a;周四(4月18日)&#xff0c;黄金上涨&#xff0c;现货金报每盎司2.384.83美元&#xff0c;上涨1%。中东地区持续的紧张局势未现缓和&#xff0c;继续扶持黄金逗留在历史高价位区域。周二美联储主席鲍威尔讲话&#xff0c;对何时可能降息三缄其口…

计算机比赛什么含金量高

acm含金量不如天梯&#xff0c;和蓝桥杯是同一层次 先说结论&#xff0c;根据专家讨论结果&#xff0c;蓝桥国一水平和icpc金牌含金量一样。&#xff08;doge 赢&#xff01;瑶瑶另先&#xff01; 会统计就多统计&#xff0c;我们acmer就是爱看这种数据 https://www.gxxsjs.co…

基于ssm高校宿舍管理系统论文

摘 要 当下&#xff0c;正处于信息化的时代&#xff0c;许多行业顺应时代的变化&#xff0c;结合使用计算机技术向数字化、信息化建设迈进。以前学校对于宿舍信息的管理和控制&#xff0c;采用人工登记的方式保存相关数据&#xff0c;这种以人力为主的管理模式已然落后。本人结…

探索 Nacos反序列化漏洞CNVD-2023-45001

在软件开发领域&#xff0c;安全漏洞是一项不容忽视的重要问题。最近&#xff0c;我们的安全团队发现了一个影响到我们的Nacos 2.1.0版本的反序列化漏洞&#xff0c;可能带来严重的安全威胁。我们已经立即采取了修复措施。本文将深入探讨这些漏洞的原理、可能造成的影响&#x…

拷贝构造函数与运算符重载

目录 一、拷贝构造函数 1.概念 2.特性 二、运算符重载 1.运算符重载 2.运算符重载实现的形式 3.赋值运算符重载 一、拷贝构造函数 1.概念 拷贝构造函数是一种特殊的构造函数&#xff0c;它在创建对象时&#xff0c;使用同一类中之前创建的对象来初始化新创建的对象…

C# 动态加载dll

方式1 using System; using System.Reflection;class Program {static void Main(){string dllPath "path/to/your/library.dll"; // 替换为你的DLL文件路径Assembly myAssembly Assembly.LoadFile(dllPath);Type myType myAssembly.GetType("YourNamespace…

力扣—2024/4/18—从双倍数组中还原原数组

代码实现&#xff1a; 快排 哈希表 ——超时 /*** Note: The returned array must be malloced, assume caller calls free().*/ void swap(int *m, int *n) {int temp *m;*m *n;*n temp; }// 快排 void sort(int *a, int l, int r) { // 左闭右开if (r - l < 2) {if (r…

MIMO(多天线)通信的四种译码算法

目录 一. 介绍 二. 极大似然译码 三. 破零译码算法 四. 最小均方误差算法 五. 球形译码 一. 介绍 发射天线数记为Mt&#xff0c;接收天线数记为Mr。由此发射信号x为向量&#xff1a; 接受信号y为向量&#xff1a; 信道H为矩阵&#xff1a; 利用n代表噪声向量&#xff0c;…

axios的封装理解和基本使用

axios的配置 ruoyi的前端对axios进行了封装&#xff0c;让我们发get请求或者是post请求更加方便了。 ruoyi对axios的封装在下面文件中&#xff1a;打开文件&#xff0c;可以看到它有三个显眼的方法&#xff0c;分别是request拦截器、response拦截器和通用下载方法。ruoYi接口地…

CommunityToolkit.Mvvm笔记---ObservableValidator

ObservableValidator 是实现 INotifyDataErrorInfo 接口的基类&#xff0c;它支持验证向其他应用程序模块公开的属性。 它也继承自 ObservableObject&#xff0c;因此它还可实现 INotifyPropertyChanged 和 INotifyPropertyChanging。 它可用作需要支持属性更改通知和属性验证的…