15. 《C语言》——【如何动态内存开辟】

在这里插入图片描述

亲爱的读者,大家好!我是一名正在学习编程的高校生。在这个博客里,我将和大家一起探讨编程技巧、分享实用工具,并交流学习心得。希望通过我的博客,你能学到有用的知识,提高自己的技能,成为一名优秀的程序员。如果你有任何疑问或建议,请随时在评论区留言,让我们一起成长进步!现在,让我们开始这场知识之旅吧!



🚀个人主页:FEN03
📚收入专栏:C语言

在这里插入图片描述



文章目录

  • 📚前言
  • 📘1. 为什么要动态内存分配❓
  • 📗2. 如何去动态内存开辟❓
    • 🔖2.1 malloc
    • 🔖2.2 free
    • 🔖2.3 calloc
    • 🔖2.4 realloc
  • 👋结束语


📚前言

为什么需要动态内存开辟,如何向内存申请空间?接下来,就让我们去探讨吧~


📘1. 为什么要动态内存分配❓


在先前,我们开辟内存的方法无非是在栈区创建一个变量,或者说一个数组。

#include<stdio.h>
int main()
{int a = 0; //在栈区开辟了4个字节的空间int arr[10] = { 0 }; //在栈区开辟了40个连续字节的空间return 0; 
}

这2种内存开辟,都存在着2种特点

  1. 内存开辟的大小是固定的了。
  2. 数组在创建时,必须是指定它的长度,一旦确定大小后不能再进行更改

为了迎合更高的要求,上述的情况就不能满足了。那么为了解决这一问题,C语言引入了动态内存开辟,这样程序员就可以灵活的去申请和释放空间。

那么接下来就让我们探索如何去动态的向内存开辟。


📗2. 如何去动态内存开辟❓

那么为了实现动态内存的开辟,C语言提供了4个函数,那么接下来,就让我们去学习如何使用这些函数吧~⬇️


🔖2.1 malloc

为了实现动态内存开辟,C语言提供了malloc函数。

函数语法形式:

void* malloc (size_t size);

这个函数能够向内存开辟一块连续可用的空间,并且会返回指向这块内存空间的指针。

  1. 如果内存开辟成功,则会返回指向这块开辟好的内存的指针。
  2. 如果内存开辟失败,则会返回NULL,所以当我们使用malloc函数时,一定要检查是否开辟成功。
  3. malloc函数的返回类型是void* ,这是因为malloc函数并不知道程序员要开辟内存空间的类型,所以当程序员使用时由自己决定返回类型。
  4. 如果size为0,这一行为是标准未定义的,而且也没必要,最终的结果也是编译器决定的。

使用malloc函数需要包含头文件:

#include<stdlib.h>

我们可以使用malloc来开辟下内存空间:


#include<stdio.h>
#include<stdlib.h>
int main()
{//向内存开辟40个字节int*p = (int*)malloc(10 * sizeof(int));  //使用if语句来判断是否开辟成功,如果失败则提示错误信息以及提前结束if (p == NULL){perror("malloc"); return 1; }//...... return 0; 
}

我们进行调试看看是否开辟成功?

在这里插入图片描述

我们看到已经内存开辟成功了,这些值都是cd,也就是一些随机值。

但是malloc只是这样使用吗,其实并不是,malloc是需要搭配free函数使用的。接下来,就让我们介绍free函数吧~ ⬇️


🔖2.2 free

C语言提供了free函数,那么free函数有什么用❓,我们在前边介绍了malloc函数,是用来向内存申请空间的,那么free函数就是专门用来对动态内存开辟的空间进行释放和回收。
在生活中,我们都知道有借有还,再借不难。那么在内存中也是这个道理。


free函数的原型如下:

void free (void* ptr);
  1. 如果参数ptr指向的内存空间不是动态内存开辟的,那么free函数的行为是未定义的。
  2. 如果参数ptr是NULL,则函数什么事都不做。

free和malloc所包含的头文件一样。

#include<stdlib.h>

如何与malloc搭配使用❓❓❓

代码如下:

#include<stdio.h>
#include<stdlib.h>
int main()
{//向内存开辟40个字节int*p = (int*)malloc(10 * sizeof(int));  if (p == NULL){perror("malloc"); return 1; }//使用...... //释放内存空间free(p); p = NULL; return 0; 
}

这样free函数就能够释放p所指向的动态内存开辟的内存空间,那么为什么还需要把p置为NULL呢?

是因为,free函数虽然已经释放掉了开辟的内存空间,但是指针p还是指向这一空间,为了避免野指针,所以置为了NULL。


🔖2.3 calloc

动态内存开辟的函数不仅仅是malloc函数,C语言还提供了另一种函数:calloc

calloc函数原型:

void* calloc (size_t num, size_t size);
  1. 函数有2个参数,第一个 num 为个数,第二个 size 为字节大小,那么它会开辟程序员所要求的内存空间,并且把空间的每一个字节初始化为0(malloc,值都是cd(随机值))。
  2. 当内存开辟成功,返回的是指向该内存的指针;失败时,返回NULL ,所以当我们使用时,也和malloc一样,需要检查。

calloc函数如何向内存申请空间呢?让我们接着往下看⬇️⬇️⬇️

当我需要向内存申请40个字节大小时:

#include<stdio.h>
#include<stdlib.h>
int main()
{//calloc向内存申请40个字节空间  int* p  = (int*)calloc(10, sizeof(int)); //判断是否开辟成功if (p == NULL){perror("calloc"); return 1; }//使用..... //释放内存空间free(p); p = NULL;    return 0;
}

结果如何? 让我们来调试看看吧~

在这里插入图片描述

我们观察到,calloc函数向内存开辟的40个字节成功,并且每一个字节初始化为0。

calloc函数和malloc函数都是向内存申请空间,既然是申请,那么也需要归还内存空间,一样的都是需要free函数释放把内存还给系统。


🔖2.4 realloc

在前边,我们介绍了malloc函数和calloc函数以及free函数,最后我们介绍realloc函数。

那么我们需要先了解,realloc函数有什么用存在的意义是什么?

其实是为了让动态内存开辟更加的灵活,有时候,我们使用malloc或者calloc申请内存空间时,可能到某一时间段发现空间太大了或者不够用小了。
那么为了对内存空间进行调整,C语言呢就提供了realloc函数,这样我们就可以对内存的大小进行灵活的调整。


realloc函数原型:

void* realloc (void* ptr, size_t size);
  1. ptr是需要调整的内存地址
  2. size是调整后的大小
  3. 返回值为调整后的内存起始位置
  4. 这个函数调整会在原内存空间的基础上,还会将原来内存中的数据移动到新的内存空间
  5. realloc函数在调整内存空间时,会分为2中情况:
    情况1:当原有空间之后有着足够大的空间,那么就会在原有空间的基础上,调整大小。
    情况2:当原有空间之后没有足够大的空间,那么会另开辟一块新的空间,并且把原有空间移到新空间,再进行调整,原有空间会被释放
    在这里插入图片描述

那么如何使用realloc函数开辟内存空间? 接着往下看吧~⬇️⬇️⬇️

#include<stdio.h>
#include<stdlib.h>
int main()
{//malloc向内存开辟40个字节int* p = (int*)malloc(10 * sizeof(int));if (p == NULL){perror("malloc");return 1;}//发现不够用,那么使用realloc函数调整内存大小//调整为80个字节int* ptr = (int*)realloc(p, 20 * sizeof(int));  if (ptr != NULL){p = ptr; ptr = NULL;  }else{perror("realloc"); return 1; }//使用..... //释放内存空间free(p);p = NULL;return 0;
}

是否开辟成功?我们进行调试看看

在这里插入图片描述

我们可以看到之前malloc函数开辟的内存为40个字节,经过realloc函数调整大小后,为80个字节。


👋结束语

非常感谢您花时间阅读我的博客,希望我的分享能为您带来收获。如果您对本文有任何想法或疑问,欢迎在评论区留言交流。如果您喜欢我的博客,请继续关注,我会定期更新更多精彩内容。最后,别忘了行动起来的力量,让我们一起实践这些方法,见证自己的成长和进步!

那么到此,关于动态内存开辟就讲解完了~

再见,祝您生活愉快!

在这里插入图片描述


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

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

相关文章

CST软件眼图工具Eye Diagram Tools (中)--- Classical流程

距离上次眼图介绍快两年了&#xff0c;由于上期已经将重点推荐的方法&#xff08;statistical流程&#xff09;介绍了&#xff0c;所以一直没急着涉及这个话题。 仿真实例011&#xff1a;眼图工具Eye Diagram Tools&#xff08;上&#xff09; 先总结一下之前介绍过的内容&am…

容器:现代计算的基础设施

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

Jmeter函数二次开发说明

jmeter 二次开发使用 jmeter二次开发实现方法 使用maven依賴进行开发 导入jmeter的maven依赖&#xff0c;需要和你使用的jmeter版本一致。 <!-- https://mvnrepository.com/artifact/org.apache.jmeter/ApacheJMeter_core --> <dependency><groupId>org.ap…

uniapp,微信小程序,在map组件外与中的代码区别

需求&#xff1a;整屏地图&#xff0c;需要在地图上方编写筛选条件&#xff0c;地图中标注经纬度定位与自定义样式 次情形仅用于微信小程序&#xff0c;其他的没去验证过 1&#xff0c;在地图上方编写赛选条件&#xff0c;及其他&#xff0c;不需要根据地图经纬度进行定位&…

大模型初学者怎么入门大语言模型(LLM)?

前言 在当今的科技浪潮中&#xff0c;人工智能&#xff08;AI&#xff09;和机器学习技术已经取得了长足的进步&#xff0c;其中大模型的发展尤为引人注目。大模型&#xff0c;通常指的是拥有海量参数、能够处理复杂任务的深度学习模型&#xff0c;如自然语言处理&#xff08;…

将字符串转换为Python数据类型

ast.literal_eval() 用于将字符串转换为Python数据类型&#xff0c;如列表、字典等&#xff0c;是安全且有限制的。 eval() 可以执行任意的Python代码&#xff0c;但存在安全风险&#xff0c;应避免使用。 json.loads() 用于将JSON字符串转换为Python对象&#xff0c;如字典…

RT-DETR 详解之 Uncertainty-minimal Query Selection

引言 在上一章博客中博主已经完成查询去噪向量构造部分的讲解&#xff08;DeNoise&#xff09;在本篇博客中&#xff0c;我们将进行Uncertainty-minimal Query Selection创新点的讲解。 Uncertainty-minimal Query Selection是RT-DETR提出的第二个创新点&#xff0c;其作用是…

UE5 Sequencer 使用指导 - 学习笔记

https://www.bilibili.com/video/BV1jG411L7r7/?spm_id_from333.337.search-card.all.click&vd_source707ec8983cc32e6e065d5496a7f79ee6 Sequencer 01 1.1 调整视口 调整窗口数量 调整视口类型为Cinematic视口 视口显示网格&#xff0c;或者条件参考线 1.2 关卡动画与…

bexcel

import requests from lxml import etree from time import sleep import numpy as np from openpyxl import Workbook # 进行UA伪装 headers {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.3…

QT QString字符串去除空白方法

空白包括 \t’, ‘\n’, ‘\v’, ‘\f’, ‘\r’, ’ ’ 1.去除字符串前面的空格 QString str1 " 1 2 3 "; str1.remove(QRegExp("^ \\s*")); //结果&#xff1a;“1 2 3”2.去除字符串后面的空格 QString str2 " 4 5 6 ";str2.remove(QRegE…

架构设计-用户信息及用户相关的密码信息设计

将用户的基本信息和用户密码存放在不同的数据库表中是一种常见的安全做法&#xff0c;这种做法旨在增强数据的安全性和管理的灵活性。以下是这种做法的几个关键原因&#xff1a; 安全性增强&#xff1a; 当用户密码被单独存放在一个表中时&#xff0c;可以使用更强大的加密和哈…

计算机毕业设计 | SpringBoot+vue的教务管理系统

1&#xff0c;绪论 1.1 项目背景 在这个资讯高度发展的时代&#xff0c;资讯管理变革已经是一个更为宽泛、更为全面的潮流。为了保证中国的可持续发展&#xff0c;随着信息化技术的不断进步&#xff0c;教务管理体系也在不断完善。与此同时&#xff0c;伴随着信息化的飞速发展…

Android:UI:Drawable:View/ImageView与Drawable

文章目录 在View/ImageVIew中显示DrawableDrawable对View的更新操作在View/ImageVIew中显示Drawable API View.setBackground(Drawable) ImageView.setImagDrawable(Drawable) 源码分析 View.mBackground在View.draw(Canvas)中绘制,调用Drawable.draw(Canvas) ImageView.m…

Hexapod C-887 使用手册 -- 1

最近要做PI C-887的集成控制&#xff0c;先把使用手册看一便&#xff0c;在此记录阅读进度。 本人微信号&#xff0c;如果有项目合作&#xff0c;可以加本人微信。 1 有关此文档 在本章中 本用户手册的目标和目标群体 符号和打印规则 图 术语的定义 其它适用文件 下载手…

Python GUI 库跨平台兼容问题及解决方案

在选择 Python GUI 库时&#xff0c;跨平台兼容性是一个重要的考虑因素。不同的 GUI 库可能在不同的操作系统上表现不同&#xff0c;因此需要选择一个能够在多个平台上运行良好的库。如果我们遇到下面的问题&#xff0c;可以尝试下我整理的方法。 1、问题背景 Python 作为一门…

基于【Lama Cleaner】一键秒去水印,轻松移除不想要的内容!

一、项目背景 革命性的AI图像编辑技术,让您的图片焕然一新!无论水印、logo、不想要的人物或物体,都能被神奇地移除,只留下纯净的画面。操作简单,效果出众,给你全新的视觉体验。开启图像编辑新纪元,尽在掌控! 利用去水印开源工具Lama Cleaner对照片中"杂质"进行去除…

【Vue】获取模块内的actions方法

目标&#xff1a; 掌握模块中 action 的调用语法 (同理 - 直接类比 mutation 即可) 注意&#xff1a; 默认模块中的 mutation 和 actions 会被挂载到全局&#xff0c;需要开启命名空间&#xff0c;才会挂载到子模块。 调用语法&#xff1a; 直接通过 store 调用 $store.di…

【Go语言】面向对象编程(一):类的定义、初始化和成员方法

面向对象编程&#xff08;一&#xff09;&#xff1a;类的定义、初始化和成员方法 1 类的定义和初始化 Go 语言的面向对象编程没有 class 、 extends 、implements 之类的关键字和相应的概念&#xff0c;而是借助结构体来实现类的声明&#xff0c;如下是定义一个学生类的方法…

Virtual Memory Primitives for User Program翻译

Virtual Memory Primitives for User Program 安德鲁阿普尔&#xff08;Andrew Appel&#xff09;和李凯&#xff08;Kai Li&#xff09; 普林斯顿大学计算机科学系 摘要 传统上&#xff0c;内存管理单元&#xff08;MMUS&#xff09;被操作系统用于实现磁盘分页的虚拟内存…