动态内存管理基础详解

news2024/11/26 5:48:01

目录

1、为什么存在动态内存分配

2、动态内存函数的介绍

2.1 malloc和free

功能:

参数和返回值:

注意事项:

tip:

2.2 calloc

 2.3 realloc函数

功能:

参数和返回值:

realloc开辟空间的两种情况

realloc会顺序采取以下措施

疑问:那realloc的返回值用原有的指针接受吗?

3、常见的动态内存错误

3.1、对NULL指针的解引用操作

3.2、对动态开辟空间的越界访问

3.3、对非动态开辟的内存进行free释放

3.4、使用free释放一块动态开辟内存的一部分

3.5、对同一块动态内存多次释放

3.6、动态开辟内存忘记释放(内存泄露)开辟空间一定要释放


1、为什么存在动态内存分配

我们已经掌握的内存开辟方式有:

int a = 0;
char b[10] = {0};

但是上述的开辟空间的方式有两个特点:

  1. 空间开辟的大小是固定的。
  2. 数组在申明时,必须指定数组的长度,它所需要的内存在编译时分配。

但是对于空间的需求,不仅仅是上述的情况。有时我们需要的空间大小在程序运行的时候才知道

那数组的编译时开辟空间的方式就不能满足了。

这时候就只能采用动态内存开辟。

2、动态内存函数的介绍

2.1 malloc和free

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

功能:

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

参数和返回值:

参数是以字节为单位的一个无符号整型,返回值是void*,指向我们开辟这块空间的指针。

注意事项:
  • 如果开辟成功,则返回一个指向开辟好空间的指针。
  • 如果开辟失败,则返回一个NULL指针,因此malloc函数的返回值必须要做检查
  • 返回值的类型是void*,所以malloc函数并不知道开辟空间的类型,具体在使用的时候由使用者自己决定。
  • 如果参数size是0,malloc的行为是标准未定义的。
tip:
  • malloc申请到空间后,直接返回这块空间的起始地址不会初始化空间的内容。
  • malloc申请的内存空间,当程序退出时,还给操作系统,当程序不退出,动态生气的内存是不会主动释放的,需要用free函数来释放。
  • 每当free函数释放空间后,指针就没有被指向的内容,为了防止野指针,需要将其设为控制在(即每次使用free函数后,都需要置成空指针
  • free函数不能释放非动态开辟的内存空间,这种行为是标准未定义的
  • 如果free函数的参数是空指针,则free函数什么都不做
int main()
{
	//int arr[10];
	int* p = (int*)malloc(40);
	if (p == NULL)
	{
		perror("malloc");
		return 1;
	}
	//开辟成功
	for (int i=0;i<10;i++)
	{
		printf("%d\n", *(p + 1));
	}
	return 0;
}

2.2 calloc

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

  •  函数的功能是num个大小为size的元素开辟一块空间,并且把空间的每个字节初始化为0.
  • 与函数malloc的区别只在于calloc会在返回地址之前把申请的每个字节初始化为0

举个例子:

 2.3 realloc函数

功能:

realloc函数的出现让动态内存管理更加灵活,调整对动态内存的大小。

参数和返回值:

ptr是要调整的内存地址,size是调整之后的新大小(以字节为单位),返回值为调整之后的内存起始位置。如果ptr为空指针,那么函数的功能与malloc函数一样。

realloc开辟空间的两种情况

1、原始空间的后面空间足够

直接返回原始空间的起始地址

2、原始空间的后面空间不够

realloc会顺序采取以下措施

(1)、开辟新的空间

(2)、会将旧的空间中的数据拷贝到新的空间

(3)、释放旧的空间

(4)、返回新空间的起始地址

疑问:那realloc的返回值用原有的指针接受吗?

回答:不能,因为假如realloc增容失败,会返回空指针,而原有的指针指向的空间还没有释放,就被置成空指针,这就造成了内存泄露!因此我们应该用一个新的指针去接受,然后判断增容是否成功,如果成功,就将新指针的内容赋给原有的指针,否则程序结束。

int main()
{
	int* p = (int*)malloc(40);
	if (p == NULL)
	{
		perror(malloc);
		return 1;
	}
	for (int i=0;i<2;i++)
	{
		*p = i + 1;
		p++;
		//p[i]=i+1;
	}
	int* ret = (int*)realloc(p, 80);
	if (ret == NULL)
	{
		perror(realloc);
		return 1;
	}
	p = ret;
	for (int i=0;i<20;i++)
	{
		printf("%d\n", p[i]);
	}
	free(p);
	p = NULL;
	return 0;
}

 上面是正确的使用realloc增容的方式。如果减容,直接size输入一个小于原来的值即可。

3、常见的动态内存错误

3.1、对NULL指针的解引用操作

解决方法:判断内存开辟函数malloc/calloc/realloc返回值是否为空

3.2、对动态开辟空间的越界访问

3.3、对非动态开辟的内存进行free释放

3.4、使用free释放一块动态开辟内存的一部分

 注意此时的p指向的不是我们动态开辟空间的起始地址,而是后面相当于动态内存的一部分,此时再用free释放是不对的,free释放应该从动态内存的起始地址开始释放

不能让起始指针跑偏! 

3.5、对同一块动态内存多次释放

3.6、动态开辟内存忘记释放(内存泄露)开辟空间一定要释放

解决方法:

动态内存申请的空间不会出了作用域自动销毁,只有两种方式销毁(将内存还给操作系统):退出程序和free函数。

malloc和free函数成对使用

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SAR合成孔径雷达中几何术语定义

《合成孔径雷达成像算法与实现》 术语定义 目标 波束覆盖区 星下点 雷达轨迹 速度 方位向 零多普勒面 最短距离 最近位置 零多普勒时刻 波束宽度 目标轨迹 信号空间和图像空间 距离 斜距平面 地距 斜视角 距离横向 目标 是被SAR照射的地球表面上的一…

内存的五大分区(自用水文)

1、堆区&#xff08;heap&#xff09;——由程序员分配和释放&#xff0c; 若程序员不释放&#xff0c;程序结束时一般由操作系统回收。注意它与数据结构中的堆是两回事 2、栈区&#xff08;stack&#xff09;——由编译器自动分配释放 &#xff0c;存放函数的参数值&#xff0…

SpringMVC及注解介绍(一)

目录 1.什么是 Spring MVC&#xff1f; 2.创建一个SpringMVC项目 3.MVC定义 4.MVC和SpringMVC的关系 5.如何学SpringMVC 6.SpringMVC注解介绍 1.RequestMapping 2.ResponseBody 3.RestController Controller ResponseBody 4.更换五大注解 5.RequestMapping 是 post…

整车总线系列——FlexRay 五

整车总线系列——FlexRay 五 我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 没有人关注你。也无需有人关注你。你必须承认自己的价值&#xff0c;你不能…

【NumPy 简单入门学习】

NumPy 简单入门学习 提示&#xff1a;仅记录需要记忆的知识点和不易理解的知识点 文章目录 NumPy 简单入门学习前言一、创建数组二、多维数组切片1.切片的多种形式2.数组的数学运算3.布尔屏蔽4.Where 函数 总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#x…

【问题记录】Ubuntu 22.04 环境下,打开 VS Code 老是访问密钥环该怎么解决?

目录 环境 问题情况 解决方法 环境 VMware Workstation 16 Pro &#xff08;版本&#xff1a;16.1.2 build-17966106&#xff09;ubuntu-22.04.2-desktop-amd64 问题情况 在Ubuntu下&#xff0c;每次运行 VS Code时&#xff0c;老是提示要输入密钥密码来解锁保存在密钥环&am…

POSTGRESQL 子事务的问题与注意事项

开头还是介绍一下群&#xff0c;如果感兴趣polardb ,mongodb ,mysql ,postgresql ,redis 等有问题&#xff0c;有需求都可以加群群内有各大数据库行业大咖&#xff0c;CTO&#xff0c;可以解决你的问题。加群请联系 liuaustin3 &#xff0c;在新加的朋友会分到2群&#xff08;共…

使用conda pack进行环境迁移

起因 起因是训练服务器为了安全期间&#xff0c;限制不能联网。而且想连接A100显卡的训练服务器必须通过堡垒机方可连接&#xff08;即目标服务器既不能联网&#xff0c;也与本机不在同一个网段&#xff09; 安装工具 首先&#xff0c;使用 conda env list 查看所有环境&…

Data与Java8中的LocalDate相互转换

一、前言 Date这个类在java.util包中&#xff0c;始于jdk1.0。后来在jdk1.8时&#xff0c;针对日期类进行了一个大的更新&#xff0c;专门新建了java.time包&#xff0c;新的日期类LocalDateTime就在这个包中。 日常工作中&#xff0c;很容易碰到旧日期类Date&#xff0c;与新…

回归预测 | MATLAB实现TCN-GRU时间卷积门控循环单元多输入单输出回归预测

回归预测 | MATLAB实现TCN-LSTM时间卷积长短期记忆神经网络多输入单输出回归预测 目录 回归预测 | MATLAB实现TCN-LSTM时间卷积长短期记忆神经网络多输入单输出回归预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.Matlab实现TCN-GRU时间卷积门控循环单元多…

C语言数据在内存中的存储

目录 前言 本期内容介绍 一、数据类型的介绍 1.1类型的意义&#xff1a; 1.2C语言中是否有字符串类型&#xff1f; 1.3类型的基本归类 整型家族&#xff1a; 浮点型&#xff08;实型&#xff09;家族&#xff1a; 构造&#xff08;自定义&#xff09;类型&#xff1a;…

通过 CSS 的样式实现语音发送动效类似声音震动的效果

实现效果&#xff1a;一般用于发送语音的时候&#xff0c;出现动画效果 //模版部分 <view class"musical-scale"><view class"scale"><view class"em" v-for"(item,index) in 15" :key"index"></view…

记录这这段时间发生的事情。

当做后端的时候总是被骂做前很丑。成为一个UI设计师与后端工程师才会更加完美。 尝试着做一个主页面。 创建了一个主页面 的表格index。 收录了希望发送到主页的&#xff0c;的帖子。 并且&#xff0c;可以填写是否可以。 一个看起来不错的主页。 标题设计的左右框。 这种框…

自动化运维——Ansible学习(四)——roles角色

目录 一、roles概述 二、角色的使用 1.角色(roles)&#xff1a;角色集合 2.roles建议存放位置 3.调用角色的方法 (1)调用角色方法1 (2)调用角色方法2 4.完整的角色架构 5.roles playbook tags使用 三、Ansible Roles目录编排 四、roles目录 (一)roles目录结构 …

剑指offer简单题01-10

01 import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规定的值即可** * param numbers int整型一维数组 * return int整型*/public int duplicate (int[] numbers) {// write code hereint…

【计算机视觉|人脸识别】 facenet-pytorch 项目中文说明文档

下文搬运自GitHub&#xff0c;很多超链接都是相对路径所以点不了&#xff0c;属正常现象。点击查看原文档。转载请注明出处。 原作者暂时并未对我的提交做出回应&#xff0c;这里同步提交到CSDN&#xff0c;点击查看项目源码 使用 Pytorch 进行人脸识别 Click here to return …

git 和adb

一、git 1、git的作用 git是一个版本控制系统&#xff0c;是一种记录一个或若干文件内容变化&#xff0c;以便将来查阅特定版本修订情况的系统。 我的理解就是代码管理器&#xff1a; 第一点你可将代码备份到git仓上&#xff1b; 第二点可记录的你修改记录&#xff1b; 第三点…

Vue中TodoLists案例_删除

与上一篇Vue中TodoList案例_勾选有三个文件变化了 App.vue&#xff1a;添加了一个deleteTodo根据id删除方法&#xff0c;传递给儿子组件MyList <template><div id"root"><div class"todo-container"><div class"todo-wrap"…

Android ObjectBox数据库的使用与详解

一、介绍 Room数据库 之前我已介绍了jetpack组件的数据库&#xff1a;Room&#xff0c;有小伙伴需要了解Room数据库可以查看这个地址&#xff1a;Android JetPack组件之Room数据库的集成与详解_android room数据库_蜗牛、Z的博客-CSDN博客 数据库的性能对设备来说很重要&#…

【雕爷学编程】Arduino动手做(168)---ATTINY85迷你USB开发板

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…