C语言——动态内存管理(malloc、calloc、realloc、free)

C语言动态内存管理

  • 一、动态内存管理库函数介绍
    • 1.为什么存在动态内存管理
    • 2.动态内存管理函数
      • (a)malloc
      • (b)free
      • (c)calloc
      • (d)realloc

一、动态内存管理库函数介绍

1.为什么存在动态内存管理

我们已经掌握的内存开辟方式有:
在栈空间上开辟内存空间

int val = 20;//在栈空间上开辟四个字节
int arr[10] = {0};//在栈空间上开辟连续的是个整形空间,40个字节
在栈空间开辟内存空间的特点:
(1)空间开辟的大小是固定的
(2)数组在申明的时候必须指定数组的长度,它所需要的内存在编译时分配
(3)对于空间的需求,不仅仅基于以上的情况,有时候我们需要的空间大小在程序运行的时候才能知道,
那数组的编译时开辟空间的方式就不能满足了。
这时候就只能试试动态存开辟了。

2.动态内存管理函数

(a)malloc

下面我们来了解库函数的介绍
C语言——动态内存管理(malloc、calloc、realloc、free)_第1张图片

1.void* —— 返回值是void* 类型的指针,这里值返回开辟好的内存空间的起始地址,
如果内存开辟失败将会返回一个NULL指针,因此malloc的返回值一定要检查
2.size_t  size —— 指的是在开辟size个字节大小连续的内存空间
3.动态内存的开辟都是在堆区上开辟的,使用结束是需要返还给操作系统的

malloc()函数使用实例

int main()
{
	//使用malloc在堆区开辟40个字节大小的内存空间
	int* arr = NULL;
	int* p = (int*)malloc(40);
	if (p == NULL)
	{
		printf("开辟内存失败!\n");
		return;//如果内粗开辟失败直接返回,程序不需要进行下去
	}
	arr = p;
	for (int i = 0; i < 10; i++)
	{
		//给开辟好的内存空间赋值
		arr[i] = i;
	}
	//打印输出
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	free(arr);
	arr = NULL;
	return 0;
}

(b)free

库函数介绍:
C语言——动态内存管理(malloc、calloc、realloc、free)_第2张图片

1.此函数不需要返回值
2.void* ptr —— 指传入开辟好的内存空间地址
3.上面介绍在堆区上开辟的内粗空间是需要返还操作系统的,C语言当中是有专门回收动态开辟的内存函数——free(),当然,程序结束之后也会自动释放。

free()函数使用实例:
还是以以上malloc开辟的内存空间为例子

int main()
{
	//使用malloc在堆区开辟40个字节大小的内存空间
	int* arr = NULL;
	int* p = (int*)malloc(40);
	if (p == NULL)
	{
		printf("开辟内存失败!\n");
		return;//如果内粗开辟失败直接返回,程序不需要进行下去
	}
	arr = p;
	for (int i = 0; i < 10; i++)
	{
		//给开辟好的内存空间赋值
		arr[i] = i;
	}
	//打印输出
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	free(arr);//这时候我们已经使用完毕,释放内存返还操作系统
	arr = NULL;//此时这块地址已经不属于我们使用,故要将它赋为空指针
	return 0;
}

(c)calloc

库函数介绍:
C语言——动态内存管理(malloc、calloc、realloc、free)_第3张图片

C语言还提供了一个函数叫calloc,calloc函数也是用来开辟动态内存分配
(1)void* —— 返回一个void*类型的指针,指的是开辟好的内存的空间的起始地址,
如果内存开辟失败也是会返回一个NULL类型的指针,故函数的返回一定要进行判断
(2)size_t num —— 开辟内存的空间类型(比如int、char等等)的数量
(3)size_t size —— 数据类型的大小,单位为字节
(4)内存的开辟是在堆区上完成的
(5)calloc()函数与malloc()函数的区别只在于calloc会返回地址之前把申请的空间的每个字节都初始化为0

calloc()函数使用实例:

//使用calloc函数的在内存上开辟10个元素整形数组
int main()
{
	int* arr = NULL;
	int* p = (int*)calloc(10, 4);
	if (p == NULL)
	{
		printf("内存开辟失败!\n");
		return;//内存开辟失败直接返回,无须进行下一步
	}
	arr = p;
	//开辟好的内存空间给它赋值
	for (int i = 0; i < 10; i++)
	{
		arr[i] = i;
	}
	//打印输出
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	//释放内存,防止内存泄露
	free(arr);
	arr = NULL;
	return 0;
}

(d)realloc

库函数介绍:
C语言——动态内存管理(malloc、calloc、realloc、free)_第4张图片

(1)有时我们发现申请的空间过小,有时候发现申请的空间过大,那为了合理的使用内存,我们一定会对内存的大小做灵活的调整。那realloc()函数就可以做到对动态开辟的内存大小做出调整。
(2)void* —— 函数返回一个在堆区调整好的内存起始地址
(3)void* ptr —— 用malloc()函数或者calloc()函数开辟好的内存的起始地址
(4)size_t size —— 要调整的内存新大小,单位为字节
(5)这个函数调整原内存空间大小的基础上,还会将原内存的数据移动到新的空间

realloc()函数使用实例:

int main()
{
	int* arr = NULL;
	int* p = (int*)malloc(10*sizeof(int));
	if (p == NULL)
	{
		printf("开辟内存空间失败!");
		return;
	}
	arr = p;
	//给开辟的内存空间赋值
	for (int i = 0; i < 10; i++)
	{
		arr[i] = i;
	}
	//打印输出
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
	//当我们的内存不够的时候,用realloc()函数进行调整
	int* ptr = (int*)realloc(p, 20*sizeof(int));
	if (ptr == NULL)
	{
		printf("扩容失败!");
		return;
	}
	arr = ptr;
	//对扩容后的内存继续使用
	for (int i = 10; i < 20; i++)
	{
		arr[i] = i;
	}
	for (int i = 0; i < 20; i++)
	{
		printf("%d ", arr[i]);
	}
	free(arr);
	arr = NULL;
	return 0;
}

C语言——动态内存管理(malloc、calloc、realloc、free)_第5张图片

每个人的成长和进步都离不开点点滴滴的积累,如果小编的内容对您有所帮助,希望友友们三连加关注哦,你的支持是小编创作的最大动力。

你可能感兴趣的:(C语言——动态内存管理(malloc、calloc、realloc、free))