动态内存管理函数(malloc,calloc,realloc,free)

动态内存函数

1.1malloc和free

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

void* malloc (size_t size);

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

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

使用malloc开辟空间实例: 

#define  _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
int main()
{char* p = (char*)malloc(10);if (p == NULL){perror("malloc");return 1;}int a = 97;for (int i = 0; i < 10; i++){*p = a;printf("%c ",*p);a++;}free(p);p = NULL;return 0;
}

在上面的代码中我们看到了陌生的free函数,这个函数是做什么用的呢?

可以看到标题写的malloc和free函数是搭配在一起来使用的,我们既然向内存借用申请了空间,那么在结束的是时候一定要free释放掉我们借来的“东西”。 

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

void free (void* ptr);

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

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

1.2calloc

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

void* calloc (size_t num, size_t size);

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

calloc函数实例:

#define  _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>int main()
{int* p = (int*)calloc(10, sizeof(int));//开辟10个整型大小的空间----40字节if (p == NULL){perror("calloc");return 1;}free(p);p = NULL;return 0;
}

 

 开辟出来的40个字节的内存空间在最初就被初始化为0了

1.3realloc

realloc函数的出现让动态内存管理更加灵活。
有时会我们发现过去申请的空间太小了,有时候我们又会觉得申请的空间过大了,那为了更合理使用内存,我们会对内存的大小做灵活的调整。那 realloc 函数就可以做到对动态开辟内存大小进行二次调整。
void* realloc (void* ptr, size_t size);
  • ptr 是要调整的内存地址
  • size 是调整之后新大小
  • 返回值为调整之后的内存起始位置。
  • 这个函数在调整原内存空间大小的基础上,还会将原来内存中的数据移动到新的空间。

realloc在调整内存空间的是存在两种情况:

  • 情况1:原有空间之后有足够大的空间
  • 情况2:原有空间之后没有足够大的空间

  •  当是情况1 的时候,要扩展内存就直接原有内存之后直接追加空间,原来空间的数据不发生变化。
  • 当是情况 2 的时候,原有空间之后没有足够多的空间时,扩展的方法是:在堆空间上另找一个合适大小的连续空间来使用。这样函数返回的是一个新的内存地址
#include <stdio.h>
int main()
{int* ptr = (int*)malloc(100);if (ptr != NULL){//业务处理}else{exit(EXIT_FAILURE);}//扩展容量//代码1ptr = (int*)realloc(ptr,INT_MAX);//这样可以吗?(如果申请失败会如何?)//更改申请的内存空间大小,如果更改的时候后续空间不足会发生原申请的内存空间指针丢失的后果//业务处理free(ptr);return 0;
}

正确使用方式应该是额外使用一个变量来接收  realloc  开辟的内存空间的地址,如果开辟成功则返回地址再赋给ptr,这样就保证了原来开辟空间的地址不会丢失,避免造成内存泄漏

 正确方式:

#include <stdio.h>
int main()
{
int *ptr = (int*)malloc(100);
if(ptr != NULL)
{
//业务处理
}
else
{
exit(EXIT_FAILURE);
}
//扩展容量//正确恰当的方式避免出现内存泄漏问题:
int*p = NULL;
p = realloc(ptr, 1000);
if(p != NULL)
{
ptr = p;
}
//业务处理
free(ptr);
return 0;
}

感谢支持!

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

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

相关文章

开源大模型正在“杀死”闭源?

点击关注 文丨郝 鑫&#xff0c;编丨刘雨琦 “OpenAI不足为惧&#xff0c;开源会慢慢赶上来。” 彼时Hugging Face创始人Clem Delangue的一句预言&#xff0c;正在迅速成为现实。 ChatGPT横空出世7个多月后&#xff0c;7月19日&#xff0c;Llama 2宣布开源&#xff0c;并且可…

day25--JS进阶(递归函数,深浅拷贝,异常处理,改变this指向,防抖及节流)

目录 浅拷贝 1.拷贝对象①Object.assgin() ②展开运算符newObj {...obj}拷贝对象 2.拷贝数组 ①Array.prototype.concat() ② newArr [...arr] 深拷贝 1.通过递归实现深拷贝 2.lodash/cloneDeep实现 3.通过JSON.stringify()实现 异常处理 throw抛异常 try/catch捕获…

Linux读写锁的容易犯的问题

Linux读写锁的容易犯的问题 读写锁是互斥锁之外的另一种用于多线程之间同步的一种方式。 多线程对于一个共享变量的读操作是安全的&#xff0c; 而写操作是不安全的。如果在一个读很多而写很少的场景之下&#xff0c;那么使用互斥锁将会阻碍大量的线程安全的读操作的进行。在…

地震勘探——相关概念(一)

地震波的基本介绍 波前&#xff1a;波在同一时刻所到达的点所构成的面&#xff0c;这个面上构成的相位是相同的。波前的形状取决于传播介质的物理性质。我们可以用地震波动方程模拟波前变化&#xff08;波场快照&#xff09;。 射线&#xff08;Ray&#xff09;&#xff1a;是…

Unity Golang教程-Shader编写一个流动的云效果

创建目录 一个友好的项目&#xff0c;项目目录结构是很重要的。我们先导入一个登录界面模型资源。 我们先创建Art表示是美术类的资源&#xff0c;资源是模型创建Model文件夹&#xff0c;由于是在登录界面所以创建Login文件夹&#xff0c;下面依次是模型对应的资源&#xff0c…

【SkyWalking】SkyWalking是如何实现跨进程传播链路数据?

文章目录 一、简介1 为什么写这篇文章2 跨进程传播协议-简介 二、协议1 Standard Header项2 Extension Header项3 Correlation Header项 三、跨进程传播协议的源码分析1 OpenTracing规范2 通过dubbo插件分析跨进程数据传播3 分析跨进程传播协议的核心源码 四、小结参考 一、简介…

C++变量默认初始化

初始化不是赋值&#xff0c;初始化是指创建变量时赋予一个初始值&#xff0c;赋值是指将变量的当前值擦除&#xff0c;赋予新值。 如果定义变量时没有初始化&#xff0c;则变量会被系统默认初始化。“默认值”取决于变量的&#xff1a;类型位置 startmindmap * C变量默认初始…

对于无法直接获取URL的数据爬虫

在爬学校安全教育题库的时候发现题库分页实际上执行了一段js代码&#xff0c;如下图所示 点击下一页时是执行了函数doPostBack&#xff0c;查看页面源码如下 点击下一页后这段js提交了一个表单&#xff0c;随后后端返回对应数据&#xff0c;一开始尝试分析获取对应两个参数&a…

【虚拟机】桥接模式下访问外网

目录 一、桥接模式的作用原理 二、配置桥接模式实现外网访问 1、设置 VMnet0 要桥接的网卡 2、虚拟机选择 VMnet0 网卡 3、手动配置虚拟机IP 一、桥接模式的作用原理 桥接模式相当于在当前局域网里创立了一个单独的主机&#xff0c;该主机桥接到宿主主机的网卡&#xff0…

细粒度特征提取和定位用于目标检测:PPCNN

1、简介 近年来&#xff0c;深度卷积神经网络在计算机视觉上取得了优异的性能。深度卷积神经网络以精确地分类目标信息而闻名&#xff0c;并采用了简单的卷积体系结构来降低图层的复杂性。基于深度卷积神经网络概念设计的VGG网络。VGGNet在对大规模图像进行分类方面取得了巨大…

uCOSIII实时操作系统 三 移植

目录 uCOSIII简介&#xff1a; 准备工作&#xff1a; 准备基础工程&#xff1a; UCOSIII工程源码&#xff1a; UCOSIII移植&#xff1a; 向基础工程中添加相应的文件夹 向工程中添加分组 常见问题&#xff1a; 下载验证&#xff1a; uCOSIII简介&#xff1a; UCOS-I…

【Nginx学习】—Nginx基本知识

【Nginx学习】—Nginx基本知识 一、什么是Nginx Nginx是一个高性能的HTTP和反向代理的web服务器&#xff0c;Nginx是一款轻量级的Web服务器/反向代理服务器处理高并发能力是十分强大的&#xff0c;并且支持热部署&#xff0c;启动简单&#xff0c;可以做到7*24不间断运行。 …

SketchyCOCO数据集进行前景图像、背景图像和全景图像的分类

SketchyCOCO数据集进行前景图像、背景图像和全景图像的分类 import os import shutildef CopyFile(src, dst, filename):if not os.path.exists(dst):os.makedirs(dst)print(create dir: dst)try:shutil.copy(src\\filename, dst\\filename)except Exception as e:print(cop…

计算机网络-计算机网络体系结构-物理层

目录 一、通信基础 通信方式 传输方式 码元 传输率 *二 准则 2.1奈氏准则(奈奎斯特定理) 2.2香农定理 三、信号的编码和调制 *数字数据->数字信号 数字数据->模拟信号 模拟数据->数字信号 模拟数据->模拟信号 *四、数据交换方式 电路交换 报文交换…

kafka客户端应用参数详解

一、基本客户端收发消息 Kafka提供了非常简单的客户端API。只需要引入一个Maven依赖即可&#xff1a; <dependency><groupId>org.apache.kafka</groupId><artifactId>kafka_2.13</artifactId><version>3.4.0</version></depend…

力扣 -- 516. 最长回文子序列

解题步骤&#xff1a; 参考代码&#xff1a; class Solution { public:int longestPalindromeSubseq(string s) {int ns.size();vector<vector<int>> dp(n,vector<int>(n));//记得从下往上填表for(int in-1;i>0;i--){//记得i是小于等于j的for(int ji;j&l…

山体滑坡监测系统——高效、便捷的新选择

在当今社会&#xff0c;科技的进步为我们的生活和工作带来了诸多便利。而在山体滑坡监测领域&#xff0c;全球导航卫星系统&#xff08;GNSS&#xff09;的引入更是增加了数据监测的高效性和便捷性。 一、山体滑坡监测系统的基本原理 山体滑坡监测系统是由监控平台和GNSS位移…

2.6 宽带接入技术

思维导图&#xff1a; 前言&#xff1a; 我的理解&#xff1a; 1. **早期互联网接入技术的局限性**&#xff1a; - 作者首先回顾了早期用户通过电话线和调制解调器连接到互联网服务提供商&#xff08;ISP&#xff09;的方式&#xff0c;指出这种方式的速度上限是56 kbit/…

UE5.1编辑器拓展【三、脚本化资产行为,删除无引用资产】

目录 需要考虑的问题 重定向的修复函数 代码&#xff1a; 删除无引用资产 代码 需要添加的头文件和模块 在我们删除资产的时候&#xff0c;会发现&#xff0c;有些资产在删除的时候会出现有被什么什么引用&#xff0c;还有的是没有被引用。 而我们如果直接选择一片去进行…

PHP 伪协议:使用 php://input 访问原始 POST 数据

文章目录 参考环境PHP 伪协议概念为什么需要 PHP 伪协议&#xff1f; php://input为什么需要 php://input&#xff1f;更灵活的数据处理减小性能压力 发送 POST 数据HackBarHackBar 插件的获取 $_POST打开 HackBar 插件通过 HackBar 插件发起 POST 请求 基操 enable_post_data_…