【C】想动态分配内存?动态内存管理了解一下

news2024/11/16 0:03:07

目录

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

二、动态内存函数的介绍

1.malloc和free

2.calloc

3.realloc

三、常见的动态内存错误

1 对NULL指针的解引用操作

 2 .对动态开辟空间的越界访问

 3.对非动态开辟内存使用free释放

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

5.对同一块动态内存多次释放

6.动态开辟内存忘记释放(内存泄漏)


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

通过之前的学习,我们已经掌握的内存开辟方式有:

1.在栈空间上开辟四个字节
2.在栈空间上开辟10个字节的连续空间

但是上述的开辟空间的方式有两个特点:
  1. 空间开辟大小是固定的。
  2.  数组在申明的时候,必须指定数组的长度,它所需要的内存在编译时分配。
但是对于空间的需求,不仅仅是上述的情况。有时候我们需要的空间大小在程序运行的时候才能知道,那数组的编译时开辟空间的方式就不能满足了。
这时候就只能试试动态内存开辟了。

动态内存分配是C语言给予我们灵活自主分配内存空间的极大权力,但是任何事物都两面性,动态内存分配的引入,让内存空间的管理变得非常的复杂,有可能会带来一些其他的问题,让我们继续往下了解。

二、动态内存函数的介绍

动态内存管理函数

  • malloc
  • free
  • calloc
  • realloc

1.malloc和free

C 语言提供了一个动态内存开辟的函数:
void* malloc ( size_t size );
这个函数向内存申请一块 连续可用 的空间,并返回指向这块空间的指针。
  • 如果开辟成功,则返回一个指向开辟好空间的指针。
  • 如果开辟失败,则返回一个NULL指针,因此malloc的返回值一定要做检查。
  • 返回值的类型是 void* ,所以malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自己来决定。
  • 如果参数 size 0malloc的行为是标准是未定义的,取决于编译器。

malloc函数是如何开辟内存空间的呢

我们用malloc向内存申请了40个字节的空间,然后打印出来结果如上图👆

在内存中分为栈区、堆区,静态区,malloc是在堆区申请到的内存空间

malloc申请的内存空间,当程序退出时不会交还给操作系统自动释放,需要借助free函数释放空间。

C 语言提供了另外一个函数 free ,专门是用来做动态内存的释放和回收的,函数原型如下:
void free ( void* ptr );
free 函数只能用来释放动态开辟的内存。
  • 如果参数 ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的。
  • 如果参数 ptr NULL指针,则函数什么事都不做。
malloc free 都声明在 stdlib.h 头文件中。

free的使用

2.calloc

C 语言还提供了一个函数叫 calloc calloc 函数也用来动态内存分配。原型如下:
void* calloc ( size_t num , size_t size );
  • 函数的功能是为 num 个大小为 size 的元素开辟一块空间,并且把空间的每个字节初始化为0
  • 与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全0

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

3.realloc

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

 void* realloc (void* ptr, size_t size);//size为调整后新的大小

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

 

  • 当是情况1的时候,要扩展内存就直接在原有内存之后直接追加空间,原来空间的数据不发生变化。
  • 当是情况2 的时候,原有空间之后没有足够多的空间时,扩展的方法是:在堆空间上另找一个合适大小的连续空间来使用。这样函数返回的是一个新的内存地址。
由于上述的两种情况, realloc 函数的使用就要注意一些

 

 代码

int main()
{
	int* p = (int*)malloc(40);
	if (p == NULL)
	{
		perror("malloc");
		return 1;
	}
	//初始化为1~10
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		p[i] = i + 1;
	}
	//增加一些空间
	int* ptr=realloc(p, 80);
	if (ptr != NULL)
	{
		p = ptr;
	}
	else
	{
		perror("realloc");
		return 1;
	}
	//打印数据
	for (i = 0; i < 20; i++)
	{
		printf("%d\n", p[i]);
	}
	//释放
	free(p);
	p = NULL;
	return 0;
}

三、常见的动态内存错误

1 NULL指针的解引用操作

 2 .对动态开辟空间的越界访问

 3.对非动态开辟内存使用free释放

 

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

5.对同一块动态内存多次释放

6.动态开辟内存忘记释放(内存泄漏)

忘记释放不再使用的动态开辟的空间会造成内存泄漏。
切记: 动态开辟的空间一定要释放,并且正确释放 。
动态申请的内存空间
不会因为出了作用域自动销毁(还给操作系统)
只有两种方式销毁:
  1. free
  2. 程序退出

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

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

相关文章

730. 机器人跳跃问题--二分

题目&#xff1a; 730. 机器人跳跃问题 - AcWing题库 思路&#xff1a; 二分 1.当起始能量E大于最大建筑高度1e5 时&#xff0c;E的能量在整个条约过程中全程递增&#xff0c;则大于E的初始能量也必然成立&#xff08;满足二段性&#xff09;。故最小初始能量范围为[0,1e5]&a…

会声会影2023电脑破解版视频剪辑工具

本次更新不仅带来了标题动作、标题特效、转场特效、音频标记等功能的更新&#xff0c;也增强了热门的GIF创作器、定格动画制作、多语字幕、短时长转场等功能&#xff0c;让大家能体验到更加新潮的视频制作方式。会声会影2023是一款视频编辑软件&#xff0c;由Corel开发。该软件…

【Linux】Centos 8 服务器部署:阿里云域名申请免费 SSL 证书详细教程

目录 一、免费申请 SSL 证书 &#xff08;1&#xff09;打开阿里云SSL证书页面 &#xff08;2&#xff09;SSL 证书 - 免费证书&#xff08;立即购买&#xff09; &#xff08;3&#xff09;SSL 证书 - 免费证书&#xff08;创建证书&#xff09; &#xff08;4&#xff…

Path Gain and Channel Capacity for HAP-to-HAP Communications

文章目录 摘要实验仿真场景一&#xff1a; 距离变化对同海拔高度HAP的影响场景二&#xff1a;距离变化对不同海拔高度HAP通信的影响。场景三&#xff1a;平台高度和频率对HAP通信的影响四 信道容量 摘要 在这项研究中&#xff0c;我们重点分析了HAP之间的信道模型&#xff0c;…

php伪协议详解

php:// — 访问各个输入/输出流&#xff08;I/O streams&#xff09; PHP 提供了一些杂项输入/输出&#xff08;IO&#xff09;流&#xff0c;允许访问 PHP 的输入输出流、标准输入输出和错误描述符&#xff0c; 内存中、磁盘备份的临时文件流以及可以操作其他读取写入文件资源…

C++前缀和算法的应用:分割数组的最多方案数 原理源码测试用例

本文涉及的基础知识点 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 题目 给你一个下标从 0 开始且长度为 n 的整数数组 nums 。分割 数组 nums 的方案数定义为符合以下两个条件的 pivot 数目&#xff1a; 1 < pivot < n nums[0]…

区块链外包开发需要注意的问题

在进行区块链外包开发时&#xff0c;有一些关键问题需要特别注意&#xff0c;以确保项目的成功和质量。以下是一些需要考虑的问题&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.明确的需求和目标&…

公众号视频怎么下载,3个方法教你如何操作!

公众号视频怎么下载&#xff0c;今天教你如何操作下载公众号视频&#xff0c;废话不多说&#xff0c;看教程 关于分享的教程我们分享一下三种方法 1&#xff1a;公众号视频查看源代码 2&#xff1a;获取公众号小助手下载公众号视频 3&#xff1a;QQ浏览器下载法 公众号视频…

C盘满了怎么清理文件?

电脑的C盘是我们电脑存储系统文件和应用程序的一个重要盘符&#xff0c;很多人经常会遇到C盘空间不足的问题&#xff1b;虽然我们可以通过卸载程序或者删除文件来释放空间&#xff0c;但是在这个过程中往往会误删掉一些重要的文件&#xff0c;造成部分程序可能无法正常使用。 因…

python 连接oracle数据库的过程步骤(亲测有效)--windows

目录 1. 安装 cx_Oracle 模块 2. 安装 oracle 客户端 3. 连接 oracle数据库 连接oracle数据库的过程中遇到很多问题&#xff0c;不过好在一一解决了&#xff0c;特地将解决问题的过程记录下来供友友们参考~ 1. 安装 cx_Oracle 模块 具体可参考 PyCharm 安装 cx_Oracle 失败…

急需一个免费又实用的配音软件~

做自媒体的朋友肯定需要用到大量的文案配音&#xff0c;又不想自己配&#xff0c;就只能在网上找AI配音的小程序、网站和软件&#xff0c;可是找了&#xff0c;又有很多效果不好&#xff0c;情绪单调。 不过没关系&#xff0c;今天我将为大家介绍一款超实用的配音网站&#xf…

【Unity程序技巧】2D音乐中心管理器

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…

MII,RMII,GMII,RGMII区别

一、MII,GMII为百兆网口 1.MII ①引脚接线图 ②引脚定义 2.GMII ①引脚接线图 ②引脚定义 二、GMII,RGMII为千兆网口 1.GMII ①GMII引脚接线图 ②GMII引脚定义 2.RGMII ①RGMII引脚接线图 ②RGMII引脚定义 三、PCB走线注意 ① RGMII 模式下&#xff0c;MAC 的 RXD0&a…

WireShark使用入门

背景 Wireshark&#xff0c;又被称为网络封包分析软件&#xff0c;是一种开源且功能十分强大的工具。该工具的主要功能是截取各种网络封包&#xff0c;并尽可能显示出最为详细的网络封包资料。它使用WinPCAP作为接口&#xff0c;直接与网卡进行数据报文交换。 Wireshark支持W…

简单有效的方法压缩图片大小,尝试一键自动压缩!

如果图片过大&#xff0c;会占据我们过多的存储空间&#xff0c;可能会引起电脑的卡顿&#xff0c;传输的速度很慢&#xff0c;也很容易传输失败&#xff0c;这时候可以把图片压缩&#xff08;https://www.yasuotu.com/&#xff09;一下&#xff0c;那么怎么才能快速压缩图片大…

【Note】完全二叉树的类型定义

完全二叉树 完全二叉树&#xff1a;深度为k&#xff0c;结点数为n的二叉树&#xff0c;如果其结点1~n的位置序号分别与等高的满二叉树的结点1~n的位置序列一一对应&#xff0c;则为完全二叉树。 完全二叉树的特点&#xff1a; 叶子结点只可能出现在最后两层。度为1的结点个数…

关于c语言,你必须了解的运行流程

流程图 1.程序的翻译环境和执行环境 在ANSIC任何一种实现下,都存在两种环境,程序的翻译环境和执行环境 翻译环境:将源代码转换成机器指令 执行环境:用于执行代码 2.详解编译链接 简单的说一个代码从编写到看到控制台的结果分为编译链接两步即可,接下来我们将详细解释编译链接中…

6 STM32标准库函数 之 内部集成电路(I2C) 所有函数的介绍及使用

6 STM32标准库函数 之 内部集成电路&#xff08;I2C&#xff09;所有函数的介绍及使用 1. 图片有格式2 文字无格式六 库函数之内部集成电路&#xff08;I2C&#xff09;所有函数的介绍及使用前言一、图片预览&#xff0c;无格式&#xff08;CSDN&#xff09;二、 I2C库函数固件…

(链表) 25. K 个一组翻转链表 ——【Leetcode每日一题】

❓ 25. K 个一组翻转链表 难度&#xff1a;困难 给你链表的头节点 head &#xff0c;每 k 个节点一组进行翻转&#xff0c;请你返回修改后的链表。 k 是一个正整数&#xff0c;它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍&#xff0c;那么请将最后剩余的节点保…

Python-股票市场用于算法交易的人类反馈强化学习 (RLHF)

ChatGPT 的成功使人类反馈强化学习 (RLHF) 技术成为人们关注的焦点。RLHF 是一种机器学习方法,它结合了强化学习 (RL) 和人类反馈 (HF) 来改进学习过程。这篇文章将使您对 RLHF 有一个全面的了解。它描述了 RLHF 在算法交易(algo transactions)中的应用,并提供了可执行的 P…