malloc与free

2023-09-19 21:32:48

目录

前提须知:

malloc:

大意:

头文件:

申请空间:

判断是否申请成功: 

使用空间:

 结果:

整体代码:

 malloc申请的空间怎么回收呢?

注意事项:

free:



前提须知:

为什么要有动态内存分配 ?

我们已经掌握的内存开辟⽅式有:

int val = 20;//在栈空间上开辟四个字节
char arr[10] = {0};//在栈空间上开辟10个字节的连续空间
  • 上述开辟内存空间的特点——空间申请之后不容易调整,或者说不能够进行调整,且数组在申明的时候,必须指定数组的⻓度,数组空间⼀旦确定了⼤⼩不能调整。
  • 而就算是变长数组也只是说数组的大小可以使用变量来指定,而一旦数组创建好后,依然是不能调整大小
  • 而对于申请的空间大小不能灵活的调整,C语言就给了: 动态内存管理,给程序员权限,自己申请,自己使用,使用完后,自己释放。

而开辟和释放所需要用到的函数就是malloc与free

  • malloc是用来申请内存的
  • free是用来释放内存的

malloc:

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

 void* malloc (size_t size);

大意:

想要多少字节就向内存申请多少个字节, 申请成功后会返回一共空间的起始地址,开辟失败会返回空指针(NULL)。

头文件:

#include <stdlib.h>

申请空间:

malloc(10 * sizeof(int));
//申请10个整型的空间 - 40个字节

判断是否申请成功: 

if (p == NULL)
{
 perror("malloc");
 return 1;
}
  • 冷知识:return 0 ;表示一共主函数的结束,也表示着一个正确的返回值,而在此时的return 1;表示的是一个返回失败的意思,或是说申请空间失败。
  • return 1;也可以用return 2;或者return 3;表示,只要表示return 0;就行。 

因为申请成功会返回起始地址,而返回的类型是void*所以我们要进行使用的时候需要进行转化,且我们要使用这个空间时得找一个相对因的变量指针进行存放空间起始地址。

int *p = (int*)malloc(10 * sizeof(int));

使用空间:

int i = 0;
for (i = 0; i <10; i++)
{
    *(p + i) = i;
}

for (i = 0;i < 10; i++)
{    printf("%d",p[i]);
     return 0;
}
  •  p+i表示地址,*(p+i)表示地址所指向的元素,所以这是给每个不同地址的不同的元素赋值。
  • p[i]相当于*(p+i)

 结果:

整体代码:

int main()
{
     int *p = (int*)malloc(10 * sizeof(int));
     if (p == NULL)
   {
     perror("malloc");
     return 1;
   }
    int i = 0;
    for (i = 0; i <10; i++)
  {
    *(p + i) = i;
  }

    for (i = 0;i < 10; i++)
  {    
    printf("%d",p[i]);
    return 0;
  }

     return 0;
}

 malloc申请的空间怎么回收呢?

  1. free回收
  2. 自己使用free不释放的时候,程序结束后,也会由操作系统回收
  3. malloc是堆区上申请内存

 

注意事项:

  • 如果开辟成功,则返回⼀个指向开辟好空间的指针。
  • 如果开辟失败,则返回⼀个 NULL 指针,因此malloc的返回值⼀定要做检查。
  • 返回值的类型是 void* ,所以malloc函数并不知道开辟空间的类型,具体在使⽤的时候使⽤者⾃⼰来决定。
  • 尽量使用free函数进行回收函数,如若使用系统回收,若申请的空间过大,或进行多次申请空间,且不使用free进行回收,系统内存空间可能会出现不够
  • 如果参数 size 为0,malloc的⾏为是标准是未定义的,取决于编译器。 

free:

C语⾔提供了另外⼀个函数free,专⻔是⽤来做动态内存的释放和回收的,函数原型如下:

void free (void* ptr);

 free函数  只能  ⽤来释放动态开辟的内存。

  • 如果参数 ptr 指向的空间不是动态开辟的,那free函数的⾏为是未定义的。
  • 如果参数 ptr 是NULL指针,则函数什么事都不做。
  • malloc和free都声明在 stdlib.h 头⽂件中。
int main()
{
     int *p = (int*)malloc(10 * sizeof(int));
     if (p == NULL)
   {
     perror("malloc");
     return 1;
   }
    int i = 0;
    for (i = 0; i <10; i++)
  {
    *(p + i) = i;
  }

    for (i = 0;i < 10; i++)
  {    
    printf("%d",p[i]);
    return 0;
  }
     free(p);//释放
     p = NULL;
     return 0;
}

free(p);
p = NULL;

  • p内存放的是申请的空间的起始位置。
  • 而free只是把p指向的空间回收了。
  • 而对于以上两段代码我们还得让p指针忘记申请空间的空间起始地址,不然p会变成野指针。
更多推荐

Java实现截取视频第一帧

目录前言一、通过Java借助第三方库实现1.引用ffmpeg使用maven,导入pom依赖:工具类2.引用jcodec二、使用第三方存储自带的方法实现(如阿里云OSS、华为云OBS)前言在实际项目中,会遇到上传视频后,需要截取视频的首帧或指定帧为图片,作为展示使用的需求。这个需求本身并不难,而且网上一搜一大把,今天就针

Sui Move智能合约提供更智能和简单的编程

编写区块链和其他计算环境的代码有很多相似之处,但区块链的重点大部分都集中在构建智能合约上。智能合约部署编译后的代码,本质上是在区块链上自动执行交易的apps。Sui网络本地的Sui虚拟机使用SuiMove编程语言编写智能合约。术语“智能合约”意味着区块链网络独特的以交易为中心的环境。考虑到区块链的无需许可以及公共环境的

[设计模式]springboot优雅实现策略器模式(加入注册器实现)

优雅实现策略器模式场景废话少说,源码地址。讲解关于本文创建登陆策略创建环境(注册器)简化代码创建父类对象,也方便后期扩展具体策略实现类用户名密码登陆手机号登陆触发点调试简言场景登陆场景使用(登陆之后返回用户信息和token所做操作基本一致,杜绝多个判断)用户名密码登陆,指纹登录手机号登陆楼主之前写过一次通过注解实现的,

NoSQL之 Redis配置与优化

1、关系数据库与非关系型数据库1.1关系型数据库关系型数据库是一个结构化的数据库,创建在关系模型(二维表格模型)基础上,一般面向于记录。SQL语句(标准数据查询语言)就是一种基于关系型数据库的语言,用于执行对关系型数据库中数据的检索和操作。主流的关系型数据库包括Oracle、MySQL、SQLServer、Micros

软件设计模式系列之三———工厂方法模式

1模式的定义工厂方法模式是一种常见的设计模式,属于创建型设计模式之一,它在软件工程中用于对象的创建。该模式的主要思想是将对象的创建过程抽象化,将具体对象的实例化延迟到子类中完成,以便在不同情况下可以创建不同类型的对象,而客户端代码不需要知道实际创建的对象类型。2举例说明不同公司都生产自己的手机,就符合工厂方法模式。比如

探索GmSSL+Nginx实践及原理

前言随着大国崛起步伐的迈进,敏感单位的数据安全问题越发受到重视,数据的加密安全传输尤为重要,对于安全问题,国家自研加密算法提供了有力的保障。作为信创行业的国有企业,十分有必要在网络通信中使用国密算法加密通信,保障客户数据安全,做出客户放心满意的产品。本文将介绍如何制作出支持国密算法的nginx,及相关原理。GmSSL介

Java线程池详解

好处降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。线程池一般用于执行多个不相关联的耗时任务,

Linux底层基础知识

一.汇编,C语言,C++,JAVA之间的关系汇编,C语言,C++可以通过不同的编译器,编译成机器码。而java只能由Java虚拟机识别。Java虚拟机可以看成一个操作系统,Java虚拟机是由汇编,C,Linux等编写而成的一个操作系统(面向os)不同的芯片,底层的CISC指令集不同,所以其机器码有区别,因此汇编不能跨平

用了 TCP 协议,就一定不会丢包吗?

表面上我是个技术博主。但没想到今天成了个情感博主。我是没想到有一天,我会通过技术知识,来挽救粉丝即将破碎的感情。掏心窝子的说。这件事情多少是沾点功德无量了。事情是这样的。最近就有个读者加了我的绿皮聊天软件,女生,头像挺好看的,就在我以为她要我拉她进群发成人专升本广告的时候。画风突然不对劲。她说她男朋友也是个程序员,异地

Docker 安装

Docker官网:Docker:AcceleratedContainerApplicationDevelopmentDockerHub官网:https://hub.docker.com/前提说明CentOSDocker安装前提条件目前,CentOS仅发行版本中的内核支持Docker。Docker运行在CentOS7(6

蒙特卡洛树搜索(MCTS)在Python中实现井字游戏策略优化详细教程

1.介绍井字游戏(TicTacToe)是大家都很熟悉的一款策略游戏,两个玩家轮流在3x3的棋盘上放置自己的标记(通常是’X’和’O’),目标是在任意方向上(横、竖、斜)连续三个自己的标记。而蒙特卡洛树搜索(MCTS)则是一种广泛用于复杂策略游戏(例如围棋、象棋等)的算法。在本文中,我们将结合这两者,使用MCTS为井字游

热文推荐