29.动态内存申请

news2024/12/26 0:11:07

1.动态内存分配的概念

在数组一章中,介绍过数组的长度是预先定义好的,在整个程序中固定不变,但是在实际的编程中,往往所需的内存空间取决于实际输入的数据,而无法预先确定。为了解决上述问题,C语言提供了一些内存管理函数,这些内存管理函数可以按需要动态的分派内存空间,也可以把不再使用的空间回收再利用

2.静态分配,动态分配

静态分配

  • 在程序编译或运行过程中,按事先规定的大小分配内存空间的分配形式。int a[10]
  • 必须事先知道所需空间的大小。
  • 分配在栈区或全局变量区,一般以数组的形式。
  • 按计划分配

动态分配

  • 在程序的运行过程中,根据需要的大小自由分配所需空间。
  • 按需分配。
  • 分配在堆区,一般使用特定的函数进行分配。

3.动态分配函数

stdlib.h

1.malloc函数

void* malloc(unsigned int size);

  • 在内存的动态存储区(堆区)中分配一块长度为size字节的连续区域,用来存放类型说明符指定的类型。
  • 函数原型返回void* 指针,使用时必须做相应的强制类型转换,分配的内存空间内容不确定,一般使用memset初始化。
  • 返回值:分配空间的初试地址(分配成功)NULL (分配失败)
    在这里插入图片描述
#include<stdio.h>
#include<stdlib.h>
int main()
{
	int* p;
	int i, n;
	printf("请输入您要申请int数组的元素个数\n");
	scanf_s("%d", &n,4);
	p = (int*)malloc(n * 4);
	if (p == NULL)
	{
		printf("malloc error");
		return 0;
	}
	for (i = 0; i < n; i++)
	{
		p[i] = i;
	}
	for (i = 0; i < n; i++)
	{
		printf("p[%d]=%d\n", i, p[i]);
	}
	free(p);
	return 0;
}

在这里插入图片描述

2.free函数(释放内存函数)

  • 头文件 #include<stdlib.h>
  • 函数定义 void free(void* ptr)
  • 函数说明 free函数释放ptr指向的内存。

注意:
1)ptr指向的内存必须是malloc calloc relloc动态申请的内存
2)free后,因为没有给ptr赋值,所以ptr还是指向原来动态申请的内存,但是内存已经不能再用了,ptr变成野指针了。
3)一块动态申请的内存只能free一次,不能多次free。

3.calloc函数

  • 头文件 #include<stdlib.h>

  • 函数定义 void* calloc(size_t nmemb, size_t size);

  • size_t实际是无符号整型,它在头文件中用typedef定义出来的。

  • 函数功能:在内存的堆中,申请nmemb块,每块的大小为size个字节的连续区域。

  • 函数的返回值:申请的内存的首地址(申请成功)返回NULL(申请失败)

注意:
malloc和calloc函数都是用来申请内存的。
区别:
1)函数的名字不同。
2)参数的个数不同。
3)malloc申请的内存,内存中存放的内容是随机的,不确定的。而calloc函数申请的内存中的内容为0.

#include<stdio.h>
#include<stdlib.h>
int main()
{
	int* p;
	int i, n;
	printf("请输入您要申请int数组的元素个数\n");
	scanf_s("%d", &n, 4);
	p = (int*)calloc(n , 4);
	if (p == NULL)
	{
		printf("malloc error");
		return 0;
	}
	for (i = 0; i < n; i++)
	{
		p[i] = i;
	}
	for (i = 0; i < n; i++)
	{
		printf("p[%d]=%d\n", i, p[i]);
	}
	free(p);
	return 0;
}

在堆中申请了n块,每块的大小为4字节,即4*n个字节连续的区域。
在这里插入图片描述

4.realloc 函数(重新申请内存)

调用malloc函数和calloc函数,单次申请的内存是连续的,但两次申请的两块内存不一定连续。有些时候有这种需求,即先用malloc函数或者calloc函数申请了一块内存,还想在原先内存的基础上挨着继续申请内存。或者释放后边一部分内存。这是可以使用realloc函数。

  • 头文件 #include<stdlib.h>
  • 函数的定义 void* realloc(void* s,unsigned int newsize);
  • 函数的功能:在原先s指向的内存基础上重新申请内存,新的内存的大小为newsize个字节,如果原先内存后面有足够大的空间,就追加,如果后面的内存不够用,则realloc函数会在堆区找一个newsize字节大小的内存申请,将原先内存中的内容拷贝过来,然后释放原先的内存,最后返回新的内存地址。

char* p;
p=(char*)malloc(100)
//想要重新申请申请内存,新的大小为50个字节
p=(char*)realloc(p,50);
//p指向的内存新的大小为50个字节,100个字节后50个字节的存储空间就被释放了。
在这里插入图片描述
在这里插入图片描述
注意:malloc calloc realloc动态申请的内存,只有在free或程序结束的时候才释放。

4.内存泄漏

  • 内存泄漏的概念:申请的内存,首地址丢失,再也无法使用,也无法释放,这块内存就被泄露了。

例1:

int main()
{
char *p;
p=(char*)malloc(100);
//p指向内存了
p=“hello world”;
//从此以后,再也找不到申请的100个字节了。则动态申请的100个字节就被泄露了
return 0;
}

例2:

void fun()
{
char* p;
p=(char*)malloc(100);
//p指向内存了
}
int main()
{
fun();
fun();
return 0;
}
//每调用一次fun泄露100个字节

解决方法1

void fun()
{
char* p;
p=(char*)malloc(100);
//p指向内存了
free(p);
}
int main()
{
fun();
fun();
return 0;
}

解决方法2

void fun()
{
char* p;
p=(char*)malloc(100);
//p指向内存了
return p;
}
int main()
{
char* q;
q=fun();
free(q);
return 0;
}

总结:申请的内存,在不用的时候一定要释放内存。

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

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

相关文章

Linux 发布 JavaWeb 项目

Linux 发布 JavaWeb 项目 安装 mysql 使用 yum search mysql-community 查看是否安装下载地址&#xff1a;https://dev.mysql.com/downloads/repo/yum/ 选择自己虚拟机的版本 在此处&#xff0c;复制 链接地址&#xff0c; 然后使用命令 wget 链接地址 来进行 下载rpm 安装 …

Python解题 - CSDN周赛第23期 - 树形背包与优化

以问哥目前的水平来看&#xff0c;本期的四道题的整体难度还是中等偏上的&#xff0c;而且从结果上来看&#xff0c; 也达到了竞赛的标准&#xff08;只有三名选手拿到满分&#xff09;。也许在某些大佬看来还是太简单了&#xff0c;毕竟都是模板题&#xff0c;直接套模板就能过…

基于深度学习人脸性别识别项目

项目概述要求针对提供的人脸数据集&#xff0c;根据人脸图像预测人脸性别。本次将提供 20000 多张已经分割的人脸图像&#xff0c;要求基于人脸图像自动识别该人性别。数据集的年龄从 1 岁覆盖到 100 多岁&#xff0c;包括了白种人、黄种人、黑种人等多种种族数据。数据集存在人…

2022年“网络安全”赛项海南省赛选拔赛 任务书

2022年“网络安全”赛项海南省赛选拔赛 任务书 一、竞赛时间 共计6小时。 &#xff08;二&#xff09;A模块基础设施设置/安全加固&#xff08;350分&#xff09; 一、项目和任务描述&#xff1a; 假定你是某企业的网络安全工程师&#xff0c;对于企业的服务器系统&#xff0c…

【数据结构】二叉搜索树

一、概念二叉搜索树也叫二叉排序树。在一颗二叉搜索树中&#xff0c;他的左子树二点节点值一定比根节点的值小&#xff0c;他的右子树节点的值一定比根节点的值大。二、特点他的左子树节点的值一定比根节点的值小他的右子树节点的值一定比根节点的值大他的每一颗子树都是一颗二…

java+springboot笔记2023002

java的注解机制&#xff1a; Java主要提供了5个基础注解&#xff0c;分别是&#xff1a; Override Deprecated SuppressWarnings SafeVarargs FunctionalInterface Java元注解&#xff1a; Retention&#xff0c; Target&#xff0c; Inherited&#xff0c; Documented&#x…

算法刷题打卡第66天:极大极小游戏

极大极小游戏 难度&#xff1a;简单 给你一个下标从 0 开始的整数数组 nums &#xff0c;其长度是 2 的幂。 对 nums 执行下述算法&#xff1a; 设 n 等于 nums 的长度&#xff0c;如果 n 1 &#xff0c;终止 算法过程。否则&#xff0c;创建 一个新的整数数组 newNums &a…

MySQL索引命中与失效

目录创建表MySQL执行优化器索引的命中与失效情况总结讨论MySQL索引命中与失效&#xff0c;我们得先来创建表 创建表 SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS 0;-- ---------------------------- -- Table structure for user -- ---------------------------- DROP TABL…

java动态规划算法

使用场景 动态规划最重要的是转移方程&#xff0c;而转移方程需要递归和记忆化搜索产生的表&#xff0c;因此直接贴出转移方程是没什么用的&#xff0c;不探究如何从递归到记忆化搜索再到转移方程&#xff0c;还是很难想到怎么去得到转移方程。下面我们将从例子中探寻如何三步走…

四、Gradle项目的生命周期

文章目录四、Gradle项目的生命周期【尚硅谷】Gradle教程-讲师&#xff1a;刘辉 生活明朗&#xff0c;万物可爱&#xff0c;人间值得&#xff0c;未来可期 四、Gradle项目的生命周期 Gradle 项目的生命周期分为三大阶段&#xff1a;Initialization -> Configuration -> E…

Maestro 薛定谔软件简单分子对接案例

##参考&#xff1a; Maestro 薛定谔软件使用&#xff1a; https://www.bilibili.com/video/BV1RN411X7Te https://www.youtube.com/watch?vNkM8jjHr7f4&listPL3dxdlKx_PcfuvHwJ0RjpZFt4HjwyTr7f Maestro 薛定谔对接&#xff1a; https://www.bilibili.com/video/BV17p…

【Java多线程】线程的常用方法

测试Thread中的常用方法1.start():启动当前线程&#xff1b;调用当前线程的run()2.run():通常需要重写Thread类中的此方法&#xff0c;将创建的线程要执行的3.currentThread():静态方法&#xff0c;返回当前代码的线程4.getName():获取当前线程的名字5.setName():设置当前线程的…

MySQL逻辑删除+Mybatis-Plus = 墙裂推荐

目录前言逻辑删除使用Mybatis-Plus逻辑删除它做了什么注意写在后面的一些话前言 一般情况下&#xff0c;我们要删除一条数据&#xff0c;直接使用 delete 即可&#xff0c;就像这样&#xff1a;delete from user where id 1&#xff0c;这样做的好处是&#xff1a; 符合我们…

C进阶_字符串库函数

目录 求字符串长度 strlen 常规实现 递归实现 指针-指针实现 长度不受限制的字符串函数 strcpy 模拟实现strcpy strcat 模拟实现strcat strcmp 模拟实现strcmp 长度受限制的字符串函数 strncpy strncat strncmp 求字符串长度 strlen size_t strlen ( const c…

前端工具(运用造型)

CSS预处理器的使用方法 1、什么是css预处理器 CSS预处理器是一种专门的编程语言&#xff0c;用来为CSS增加一些编程特性&#xff08;CSS本身不是编程语言&#xff09;不需要考虑浏览器兼容问题&#xff0c;因为CSS预处理器最终编译和输出的仍是标准的CSS样式。可以在CSS预处理…

磨金石教育摄影技能干货分享|简述特效在影视制作中的四大作用

近三年因为疫情的原因&#xff0c;极少去影院去看电影。 想起来上次看电影还是去年八月份&#xff0c;当时上映的是科幻大作《沙丘》。看科幻电影&#xff0c;最大的期待就是导演编剧们对外星球与外太空场景的塑造。那些逼真的场景与炫酷的战舰航天器&#xff0c;满足了我对未知…

设计模式_结构型模式 -《适配器模式》

设计模式_结构型模式 -《适配器模式》 笔记整理自 黑马程序员Java设计模式详解&#xff0c; 23种Java设计模式&#xff08;图解框架源码分析实战&#xff09; 概述 如果去欧洲国家去旅游的话&#xff0c;他们的插座如下图最左边&#xff0c;是欧洲标准。而我们使用的插头如下图…

Kindle 可旋转桌面时钟

前言 自己的 Kindle 吃灰很久了&#xff0c;想做个时钟用&#xff0c;但是网上可选的时钟网站比较少&#xff0c;这些时钟网站里面&#xff0c;要么太简单 界面也比较丑陋&#xff0c;要么内容太多 有些本末倒置了&#xff0c;要么网址特别长 输入网址的时候太麻烦。 干脆自己…

【ROS】—— 机器人导航(仿真)—导航原理(十七)

文章目录前言1. 导航模块简介1.1 全局地图1.2 自身定位1.3 路径规划1.4 运动控制1.5 环境感知2. 导航之坐标系前言 &#x1f4e2;本系列将依托赵虚左老师的ROS课程&#xff0c;写下自己的一些心得与笔记。 &#x1f4e2;课程链接:https://www.bilibili.com/video/BV1Ci4y1L7ZZ …

Min_25筛详解

概述 Min_25是日本一个ACM选手的ID&#xff0c;这个筛法是他发明的&#xff0c;所以称之为Min_25筛。它能在亚线性复杂度求出一类积性函数的 fff 的前缀和&#xff0c;前提 是这个积性函数在质数和质数的幂位置的函数值比较好求。借助埃拉托色尼筛的思想 将原问题转化成与质因…