【34】C语言 | 动态内存管理

news2024/12/23 22:44:09

目录

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

2、动态内存函数的介绍

2.1 malloc和free

2.2 calloc

2.3 realloc


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

我们已经掌握的内存开辟方式有:
int val = 20; //在栈空间上开辟四个字节

char arr[n] = {0}; //在栈空间上开辟10个节的连续空间

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

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

但是对于空间的需求,不仅仅是上述的情况。有时候我们需要的空间大小在程序运行的时候才能知道,那数组的编译时开辟空间的方式就不能满足了。这时候就只能试试动态存开辟了。 

2、动态内存函数的介绍

2.1 malloc和free

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

void* malloc (size_t size);

  

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

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

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

void free (void* ptr); 

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

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

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

举个例子: 

//假设开辟10个整形的空间
#include<stdlib.h>
int main()
{
	//栈区开辟
	int arr[10]; 

	//动态内存开辟
	int* p = (int*)malloc(10*sizeof(int)); //void*

	//使用这些空间的时候
	if(p == NULL)
	{
		perror("main");
		return 0;
	}

	//使用
	int i = 0;
	for(i=0; i<10; i++)
	{
		*(p+i) = i;
	}
	for(i=0; i<10; i++)
	{
		printf("%d ",p[i]); // p[i] -->*(p+i)
	}

	//回收空间
	free(p);
	p = NULL; //自己动手把p置为NULL

	return 0;
}

2.2 calloc

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

void* calloc (size_t num, size_t size) 

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

 举个例子:

malloc没有作初始化

 calloc作初始化为0

 

2.3 realloc

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

函数原型如下

void* realloc (void* ptr, size_t size);

ptr 是要调整的内存地址

size调整之后新大小

返回值为调整之后的内存起始位置。

这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到 新的空间realloc在调整内存空间的是存在两种情况: 

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

举例:

#include<stdlib.h>
int main()
{
	int* p = (int*)calloc(10,sizeof(int));
	if(p == NULL)
	{
		perror("main");
		return 1;
	}
	//使用
	int i = 0;
	for(i=0; i<10; i++)
	{
		*(p+i) = 5;
	}
	//这里需要p指向的空间更大,需要20个int的空间
	//realloc调整空间
	int*ptr = (int*)realloc(p,20*sizeof(int));
	if(ptr != NULL)
	{
		p = ptr;
	}

	return 0;
}

3.常见的动态内存错误

3.1 对NULL指针的解引用操作

举例:

int main()
{
	int*p = (int*)malloc(10000000000);
	//如果没有对malloc函数的返回值做判断
	//p的值可能是NULL,就会有问题
	
	int i = 0;
	for(i=0; i<10; i++)
	{
		*(p+i) = i;
	}

	return 0;
}

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

举例:

#include<stdlib.h>
int main()
{
	int* p = (int*)malloc(10*sizeof(int));
	if(p == NULL)
	{
		return 1;
	}
	int i = 0;
	//越界访问
	for(i=0; i<40; i++)
	{
		*(p+i) = i;
	}
	free(p);
	p = NULL;

	return 0;
}

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

举例:

int main()
{
	int arr[10] = {0};
	int* p = arr;

	free(p);//使用free释放非动态开辟的空间
	p = NULL;

	return 0;
}

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

举例:

#include<stdlib.h>
int main()
{
	int* p = (int*)malloc(10*sizeof(int));
	if(p == NULL)
	{
		return 1;
	}
	int i = 0;

	for(i=0; i<5; i++)
	{
		*p++ = i;
	}
	free(p);
	p = NULL;

	return 0;
}

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

举例:

#include<stdlib.h>
int main()
{
	int* p = (int*)malloc(10*sizeof(int));

	free(p);

	//
	//
	//
	//
	free(p);//又释放一次

	return 0;
}

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

动态开辟的空间2种回收方式

1.主动free

2.程序结束

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

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

相关文章

mPEG-SS-NHS甲氧基聚乙二醇-二硫键-琥珀酰亚胺酯

mPEG-SS-NHS甲氧基聚乙二醇-双硫键-活性酯 名称&#xff1a;甲氧基聚乙二醇-双硫键-琥珀酰亚胺酯 英文名称&#xff1a;mPEG-SS-NHS 存储条件&#xff1a;-20C&#xff0c;避光&#xff0c;避湿 用 途&#xff1a;仅供科研实验使用&#xff0c;不用于诊治 外观: 固体或粘性…

【c语言进阶】动态通讯录

&#x1f680;write in front&#x1f680; &#x1f4dc;所属专栏&#xff1a; c语言学习 &#x1f6f0;️博客主页&#xff1a;睿睿的博客主页 &#x1f6f0;️代码仓库&#xff1a;&#x1f389;VS2022_C语言仓库 &#x1f3a1;您的点赞、关注、收藏、评论&#xff0c;是对我…

彭博:预订量未及预期,索尼大幅削减PS VR2首季订单

在索尼VR新品&#xff1a;PS VR2正式发货前夕&#xff0c;彭博社爆料称&#xff1a;因预订量不及预期&#xff0c;索尼已经大幅削减PS VR2首季订单量。消息人士称&#xff0c;索尼PS VR2发布后首个季度的订单目标是200万台&#xff0c;现已根据预订量减半&#xff0c;至约100万…

iOS 视频播放器开发

需求设计 做一个小学生教育辅导视频播放器。 参考小猿搜题视频播放器 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L0GsyFSt-1675164972791)(https://tva1.sinaimg.cn/large/008vxvgGgy1h9xk4fm5xfj31sx0u0mz0.jpg)] [外链图片转存失败,源站可…

Java中的JCA对基于密码的加密进行成功的蛮力搜索攻击所需的时间估计

对于JCA中基于密码的DES加密实现&#xff0c;固定一些盐和迭代计数&#xff0c;并记录加密/解密所需的平均时间;估计成功进行蛮力搜索攻击所需的时间Name: NIHAO DONG Number: 201476606 Password List:N Password 1 P$$W0rD 2 thisismypassword 3 VeryLongP$$W0rD fi…

[0CTF 2016]piapiapia(字符逃逸详解)

目录 知识点 信息收集 尝试SQL注入 源码目录扫描 代码审计 payload生成 知识点 信息泄露参数传递数组绕过字符串检测反序列化字符逃逸 信息收集 收集到了一只超可爱的小喵 尝试SQL注入 用户名不存在的回显 密码无效的回显 用户存在&#xff0c;密码错误的回显 判断闭…

STC15系列PWM功能相关功能寄存器介绍

STC15系列PWM功能相关功能寄存器介绍✨以下数据来源于stc15手册。 &#x1f4d3;增强型PWM波形发生器相关功能寄存器总表 1. 端口配置寄存器&#xff1a;P_SW2 2.PWM配青寄存器:PWMICFG CBTADC: PWM计数器归零时 (CBIF1时) 触发ADC转换 – 0:PWM计数器归零时不触发ADC转换 – …

Web3中文|亚马逊进入web3,将在春季推出NFT计划

亚马逊正向加密行业迈出第一步。 根据Blockworks 1月26日发布的报告&#xff0c;这家电子商务巨头计划在2023年春天推出一项专注于区块链游戏和相关NFT的计划。 该计划仍处于开发阶段&#xff0c;但发布的最后期限定为4月。亚马逊用户将可以体验基于区块链的游戏并领取免费的…

Python采集某乎专栏文章保存成pdf

前言 大家早好、午好、晚好吖 ❤ ~ 环境使用: Python 3.8 Pycharm wkhtmltopdf 软件 --> 文章下方名片信领取 模块使用: requests >>> pip install requests 数据请求 parsel >>> pip install parsel 数据解析 re >>> 内置模块 不需要安装…

域内委派攻击

域委派是指&#xff0c;将域内用户的权限委派给服务账号&#xff0c;使得服务账号能以用户权限开展域内活动。利用委派可获取域管理员权限 域委派主要分为三种&#xff1a; 非约束性委派 约束性委派 基于资源的约束性委派 在Windows系统中&#xff0c;只有服务账号和主机账号…

操作系统权限提升(五)之系统错误配置-PATH环境变量提权

系列文章 操作系统权限提升(一)之操作系统权限介绍 操作系统权限提升(二)之常见提权的环境介绍 操作系统权限提升(三)之Windows系统内核溢出漏洞提权 操作系统权限提升(四)之系统错误配置-Tusted Service Paths提权 注&#xff1a;阅读本编文章前&#xff0c;请先阅读系列文章…

寻找整数

问题描述 本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。 有一个不超过 10^{17}1017 的正整数 nn,知道这个数除以 2 至 49 后的余数如下表所示,求这个正整数最小是多少。 运行限制 最大运行时间:1s最大运行内存: 512M参考答案 mp = {2: 1, …

虹科动态 | 虹科HSR/PRP IP核现已支持HSR/PRP最新标准

HSR与PRP是专注于解决高可靠性自动化网络传输的技术&#xff0c;其所属的国际标准为IEC 62439。最初&#xff0c;IEC发布此项标准主要目的是为了满足IEC 61850-5中所提到的变电站自动化应用中各通信组件或服务故障所要求的恢复时间问题&#xff0c;但协议设计时的通用性&#x…

PTA L1-017 到底有多二

前言&#xff1a;本期是关于到底有多二的详解&#xff0c;内容包括四大模块&#xff1a;题目&#xff0c;代码实现&#xff0c;大致思路&#xff0c;代码解读&#xff0c;今天你c了吗&#xff1f; 题目&#xff1a; 一个整数“犯二的程度”定义为该数字中包含2的个数与其位数…

Java多线程:Future和FutureTask

一、Future Future是一个接口&#xff0c;所有方法如下&#xff1a; 上源码&#xff1a; package java.util.concurrent; public interface Future<V> {boolean cancel(boolean mayInterruptIfRunning);boolean isCancelled();boolean isDone();V get() throws Interru…

5.3 场效应管的高频等效模型

由于场效应管各级之间存在极间电容&#xff0c;因而其高频响应与晶体管相似。根据场效应管的结构&#xff0c;可得出图5.3.1(a)所示的高频等效模型&#xff0c;大多数场效应管的参数如表1所示。由于一般情况下 rgsr_{gs}rgs​ 和 rdsr_{ds}rds​ 比外接电阻大得多&#xff0c;因…

Lesson 4.5 梯度下降优化基础:数据归一化与学习率调度

文章目录一、数据归一化方法1. 数据归一化计算公式1.1 0-1 标准化1.2 Z-Score 标准化1.3 非线性标准化2. 数据归一化算法执行过程3. 数据归一化算法评价4. Z-Score 标准化算法评价及横向对比二、梯度下降算法优化初阶1. 数据归一化与梯度下降算法优化2. 学习率调度3. 小批量梯度…

RV1126笔记二十六:lvgl移植

若该文为原创文章,转载请注明原文出处。 之前做项目的时候有了解到LVGL这个开源的gui库,有QT仿真过智能家居控制界面,也在STM32上移植过。 趁着过年期间就想着把它移植到自己的开发板上看看能不能正常跑起来。虽说不难,但也花了一些功夫,因此也在这里做下总结。 下载地址…

STC15系列PWM中断控制寄存器介绍以及PWM相关示例

STC15系列PWM中断控制寄存器介绍以及PWM呼吸灯代码实现&#x1f4cc;相关篇《STC15系列PWM功能相关功能寄存器介绍》✨以下数据来源于stc15手册。 &#x1f4d3;增强型PWM波形发生器的中断控制 1.PWM中断优先级控制寄存器:IP2 PPWMFD:PWM异常检测中断优先级控制位。 当PPWMFD…

微信小程序员010宠物交易系统商城系统

宠物交易系统商城系统分为用户小程序端和管理员后台网页端&#xff0c;其中后端是采用java编程语言&#xff0c;mysql数据库&#xff0c;idea开发工具&#xff0c;ssm框架开发&#xff0c;本系统分为用户和管理员两个端&#xff0c;其中用户可以在小程序端进行注册登陆&#xf…