首页 > 系统相关 >c语言:动态内存管理中的malloc和free,calloc和realloc

c语言:动态内存管理中的malloc和free,calloc和realloc

时间:2024-10-31 18:16:49浏览次数:3  
标签:10 malloc int realloc free 空间 ptr

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

通过之前的学习,我们已经掌握的内存开辟方式有:

int a = 20;//在栈空间上开辟四个字节
char arr[10] = {0};//在栈空间上开辟10个字节的连续空间

上述空间的开辟的大小是固定的

数组在申明的时候,必须指定数组的长度,数组空间一旦确定了大小不能进行调整。

但是c语言引入了动态内存开辟,可以自己申请和释放空间,比较灵活。

malloc和free

malloc

void* mallloc (size_t size);

是c语言提供的一个开辟动态内存的函数。

返回值是void*,所以并不知开辟空间的类型,具体在使用的时候自己做决定。

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

例如:申请10个整型的空间

#include<stdio.h>
int main()
{
	//申请10个整型的空间 
	int* p = (int*)malloc(10*sizeof(int));
	return 0;
 } 

但是空间的开辟不一定都是成功的,所以要进行判断,如果开辟成功就返回起始地址。

如果开辟失败,就返回一个NULL指针,所以对返回值一定要做好检查

#include<stdio.h>
int main()
{
	//申请10个整型的空间 
	int* p = (int*)malloc(10*sizeof(int));
	//对内存的申请是否成功,进行判断。 
	if(p ==NULL)
	{
		//空间开辟失败
		perror("malloc");
		return 1; 
	 } 
	return 0;
 } 

free

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

void free(void* ptr);

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

如果参数ptr 指向的空间不是动态开辟的,那么free函数的行为是未定义的。

如果参数ptr是NULL指针,则函数什么事都不用做。

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

例如:

#include<stdio.h>
#include<stdlib.h>
int main()
{
	int* ptr=NULL;
	int num=0;
	scanf("%d",&num);
	ptr = (int*)malloc(num*sizeof(int));
	//对内存的申请是否成功,进行判断。 
	if(*ptr ==NULL)
	{
		//空间开辟失败
		perror("malloc");
		return 1; 
	 } 
	 int i=0;
	 for(i=0;i<num;i++)
	 {
	 	*(ptr+i)=0;
	  } 
	  free(ptr);//释放ptr所指向的动态内存。
	  ptr = NULL; 
	return 0;
 } 

一旦free之后,p指完的空间,不属于当前程序,但是可以找到。

为了防止ptr成为野指针,所以最后加一个ptr = NULL

局部数组不可以释放,malloc和free最好成对使用。

calloc和realloc

calloc

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

void* calloc (size_t num,size_t size);

函数的功能为num个大小为size的元素开辟一块空间,并且把空间的每个字节初始化为0.

与函数malloc的区别只在于calloc会在返回地址之前把申请的空间的每一个字节初始化为全0.

#include<stdio.h>
#include<stdlib.h>
int main()
{
	//申请10个整形的空间
	//malloc(10*sizeof(int));
	int *p = (int*)calloc(10,sizeof(int));
	if(p==NULL)
	{
		perror("calloc");
		return 1;
	 } 
	 //使用空间
	 int i=0;
	 for(i=0;i<10;i++)
	 {
	 	printf("%d ",p[i]);//*(p+i)
	  } 
	  //释放
	  free(p);
	  p = NULL; 
	return 0;
}

如果我们对内存空间的内容要求初始化,那么可以很方便的使用calloc函数来实现。

realloc

realloc函数的出现是让动态内存管理更加灵活。

有时我们发现过去申请 的空间太小了,或者太大了,为了合理的使用内存,我们一定会对内存的大小做灵活的调整,realloc函数就可以对动态开辟内存的大小进行调整。

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

     ptr是调整的内存地址

    size 调整之后的大小

返回值为调整之后的内存的起始地址

这个函数调整内存空间的大小的基础上,还会将原来内存中的数据移动到新的空间

分为两种情况

int main()
{
	int* ptr = (int*)malloc(20);
	//.....
	if(ptr != NULL)
	{
		int* tmp = realloc(ptr,40);
		//...
	}
	return 0;
}

1,原有的空间由足够大的空间。

2,原有的空间之后没有足够的空间。

(1)对于第二种:如果后续的空间不够,realloc函数直接在内存的堆区找一块新的满足大小的空间

(2)将旧的数据,拷贝到新的空间

(3)释放新的空间

(4)返回新的地址

#include<stdio.h>
int main()
{
	//申请10个整型的空间 
	int* ptr = (int*)malloc(10*sizeof(int));
	//对内存的申请是否成功,进行判断。 
	if(ptr != NULL)
	{
		//业务处理 
	 } 
	 else 
	 {
	 	return 1;
	  } 
	  //扩展容量
	  //代码1--直接将realloc的返回值放到ptr中
	  ptr = (int*)realloc(ptr,1000);//这样的方式正确吗?
	  //代码2--先将realloc函数的返回值放在p中,不为NULL,再放在ptr中
	  int* p = NULL;
	  p = realloc(ptr,1000);
	  if(p != NULL)
	  {
	  	ptr = p;
	   } 
	   //业务处理
	   free(ptr); 
	return 0;
 } 

标签:10,malloc,int,realloc,free,空间,ptr
From: https://blog.csdn.net/2401_83201682/article/details/143391427

相关文章

  • Linux:free指令
    学习自:Linuxfree命令使用教程(free指令)(查看内存、系统内存、内存占用、内存使用情况)_free命令看到的内存-CSDN博客free命令详解-CSDN博客1、概述free指令用于显示系统中未使用和已使用的物理和swap区总量。2、语法free[-bkmght][-s秒数]3、参数参数用途b以......
  • Data-Free,多目标域适应合并方案,简单又有效 | ECCV'24
    来源:晓飞的算法工程笔记公众号,转载请注明出处论文:Training-FreeModelMergingforMulti-targetDomainAdaptation论文地址:https://arxiv.org/abs/2407.13771论文代码:https://air-discover.github.io/ModelMerging创新点对域适应的场景解析模型中的模式连通性进......
  • 第六章 FreeRTOS 任务相关 API 函数
    6.1任务创建和删除API函数FreeRTOS的任务创建和删除API函数如表:函数xTaxkCreate()此函数用来创建一个任务,任务需要RAM来保存与任务有关的状态信息(任务控制块),任务也需要一定的RAM来作为任务堆栈。如果使用函数xTaskCreate()来创建任务的话那么这些所需的RAM......
  • 【论文笔记】C$^2$RL: Content and Context Representation Learning for Gloss-free
    ......
  • FreeRTOS 4:任务相关数据结构
    任务相关数据结构任务控制块TCB_tFreeRTOS的每个任务都有⼀些属性需要存储,FreeRTOS把这些属性集合到⼀起⽤⼀个结构体来表⽰,这个结构体叫做任务控制块:TCB_t,在使⽤函数xTaskCreate()创建任务的时候就会⾃动的给每个任务分配⼀个任务控制块。此结构体在文件tasks.c中有定......
  • FreeRTOS同步互斥与通信(有缺陷的同步示例,有缺陷的互斥示例)
    同步互斥1.同步同步指的是协调多个线程或进程的执行顺序,以确保某些操作按预期的顺序进行。同步主要用于解决依赖关系的问题,确保线程之间的协调。目的:保证操作的顺序,确保某些条件成立前不进行后续操作。实现方式:信号量:控制访问共享资源的数量,可以限制同时访问的线......
  • FreeRtos的移植
    一.前言之前移植过freertos操作系统,涉及到计算机和操作系统的底层,特此详细记录下这些知识点。至于具体的详细步骤,就不给出了,网上有很多参考,这里只分析“重点”。笔者的cpu内核是cotex-M3.二.3个重点函数vPortSVCHandler():加载第一个任务的中断处理函数。xPortPendSVHandler()......
  • Free5GC源码研究(7) - NSSF研究
    本文研究NetworkSliceSelectionFunction(NSSF)主要实现的功能NSSF的概念NSSF,也就是网络切片选择功能,负责根据用户请求和网络的配置来选择最合适的网络切片实例(NetworkSliceInstance,NSI)来服务用户设备。所谓网络切片,是5G核心网的重要概念,允许运营商在同一物理基础设施上......
  • freeswitch的话单处理
     概述freeswitch是一款简单好用的VOIP开源软交换平台。如果对cdr话单要求不高,可以直接使用fs的原始话单文件,使用脚本做一些简单的统计。环境CentOS7.9freeswitch1.10.7docker话单配置修改conf/autoload_configs/cdr_csv.conf.xml文件如下。<paramname="legs"valu......
  • C++ 内存管理 堆和栈、内存泄漏、内存分配、指针与内存、智能指针、malloc和free、new
    1.堆和栈的区别1.**管理方式**:-**栈**:自动管理。当函数调用时,局部变量会自动分配在栈上。函数执行完毕后,这些变量会自动释放。-**堆**:手动管理。程序员需要使用`new`来在堆上分配内存,并在不再需要时使用`delete`来释放。2.**使用方式和寿命**:-**栈**:用......