浅谈动态内存——数据结构基础

本文详细介绍了C语言中动态内存管理的四个关键函数:malloc用于分配内存,free用于释放内存,calloc用于分配并初始化内存,realloc则用于内存的扩展和收缩。每个函数的使用方法、注意事项和示例代码都有清晰的阐述。
摘要由CSDN通过智能技术生成

目录

1.定义

2.函数分类

        2.1  malloc

        2.2 free

        2.3 calloc

        2.4 realloc

3.小结             


1.定义

所谓动态内存分配(Dynamic Memory Allocation)就是指在程序执行的过程中动态地分配或者回收存储空间的分配内存的方法。动态内存分配不像数组等静态内存分配方法那样需要预先分配存储空间,而是由系统根据程序的需要即时分配,且分配的大小就是程序要求的大小。

2.函数分类

        【使用内存分配函数时添加头文件#include<stdlib.h>】

        2.1  malloc

                2.1.1函数原型分析

//函数原型
void *malloc(unsigned int size)
//其中void* 表示malloc返回的内存空间类型未知,需要程序员根据自己的需要进行设计
//size表示空间长度为size
//该函数返回所申请空间的起始地址,需要用对应的指针进行接收

                2.1.2 利用函数申请空间

//[进行申请]
//(以申请int类型的长度为40字节的内存空间为例)
int* p=(int*)malloc(40)
//【注】40字节的int类型——10个int

                2.1.3 进行检验(可能会出现未分配内存空间的情况)

if(p==NULL){
		printf("%s\n",strerror(errno));
		return 1;
	}

                2.1.4 使用分配的内存空间

	//[进行存放]
	int i=0;
	for(i=0;i<10;i++){
		*(p+i)=i+1;
	}
	//[进行打印]
	for(i=0;i<10;i++){
		printf("%d ",*(p+i));
	}

        2.2 free

        由动态内存的定义知,动态内存的分配不仅包含分配空间,同时还包含回收空间。

我们使用free( )函数进行空间的回收。

//[释放内存]
	free(p);//释放p指向的空间
	p=NULL;//将p指针赋值为空

        2.3 calloc

//函数原型
void* calloc(unsigned int num,unsigned int size);
//在内存的动态存储区中分配num个长度为size的连续空间

                2.3.1 利用函数申请空间并进行检验

	int* p=(int*)calloc(10,sizeof(int));
//申请了10个int类型的空间
	if(p==NULL){
		perror("calloc");
		return 1;
	}

                2.3.2 使用空间并释放

	//使用
	int i=0;
	for(i=0;i<10;i++){
		printf("%d ",*(p+i));
	}
	//释放
	free(p);
	p=NULL;

                【注意!】此处使用calloc函数申请空间后,在未对内存空间赋值的情况下直接打印空间内的值,结果为0。

                 这是因为calloc申请好空间后,会将空间初始化为0,返回起始地址;

而malloc函数在申请好空间后,会直接返回起始地址,所以在2.1.4中我们需要先在内存中存放数据,然后再打印空间中的数据。

        2.4 realloc

           特点:让动态内存管理更加灵活,可以对已开辟的空间进行扩容

//函数原型 
	void* realloc(void* ptr,size_t size);
//ptr指向之前被realloc,malloc,calloc开辟的空间
//size指新开辟空间的大小

                2.4.1 使用malloc函数开辟空间并使用

	int *p=(int*)malloc(5*sizeof(int));
//5*sizeof(int)表示开辟5个int类型的空间
//等同于:int* p=(int*)malloc(20);
	if(p==NULL){
		perror("malloc");
		return 1;
	}
	//使用malloc开辟的空间
	int i=0;
	for(i=0;i<5;i++){
		*(p+i)=1;
	}

                2.4.2 使用realloc函数进行扩容

	//需要增容10个新的空间
	int* ptr=(int*)realloc(p,10*sizeof(int));
	

                【注意!】扩容分为两种类型:原地扩容(红色标识)、异地扩容(黄色标识)

                为满足以上两种情况,空间重分配成功后旧内存会被自动释放,旧指针变成了野指针 。

因此,可以将扩容后的新指针(ptr)赋给旧指针(p),即旧指针(p)指向已扩容完成的新空间。

//如果空间开辟成功
    if(ptr!=NULL){
		p=ptr;
	}
	//打印增容的空间元素
	for(i=0;i<10;i++){
		printf("%d ",*(p+i));
	}
	free(p);
	p=NULL;

         结果如下图所示:

               可知此时已开辟的存放int类型元素的空间中,前5个元素仍未1,其余5个元素未被初始化。

        对空间进行赋值

	//使用增容的空间
	for(int i=0;i<10;i++){
		*(p+i)=i;
	}

        结果如下图所示: 

 

                2.4.3 realloc申请内存

                realloc除了对已开辟的空间进行扩容外,还可以直接开辟空间。功能相当于malloc。

   int* p=(int*)realloc(NULL,40);
//40指开辟40个字节用于存放int类型的元素
//等同于 int* p=(int *)realloc(NULL,sizeof(int)*10);

3.小结             

        至此,动态内存分配的四种函数已经介绍完成,下面通过一个图表比较它们的异同。

动态内存函数的区别
函数                  作用是否初始化元素
malloc开辟size个字节的内存空间        否

calloc

开辟num个可以存放x类型的内存空间        是
realloc

1.对已经开辟的空间进行扩容

2.直接开辟size个字节的内存空间

         否
free释放已开辟的内存空间          /

下一期将分析动态内存开辟时易遇到的问题。
 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值