C语言☀️动态内存管理及相关函数

Posted Go-ly

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言☀️动态内存管理及相关函数相关的知识,希望对你有一定的参考价值。

目录

一、为什么存在动态内存分配

二、动态内存函数

 malloc和free

calloc

realloc


一、为什么存在动态内存分配

 之前我们学过的开辟空间的方式就是如下两种:

int main()
{
	int a = 5;
	char ch = 'b';
	int arr[20] = { 0 };
}

以上的开辟内存的方式都是开辟好内存之后所开辟的内存是固定的,不能改变的,这种开辟方式不够灵活

C语言里面的动态开辟内存就解决了这个问题

在学习C语言的时候通常大致将内存划分为三部分:栈区,堆区,静态区

 动态开辟内存就是在栈上面开辟的空间

二、动态内存函数

 malloc和free

malloc函数原型

void *malloc( size_t size );

参数:size_t size,就是想要开辟多大一块空间(以字节为单位),类型为无符号整型

返回值:void*类型的指针,就是返回所开开辟的这块空间的起始地址,将来这块空间用来存什么类型的数据是不确定的,所以是void*类型;如果内存开辟失败,就返回空指针(NULL)

头文件:<stdlib.h>

如果参数size 为0,malloc的行为是标准是未定义的,取决于编译器

如下示例:

#include <stdio.h>
#include <stdlib.h>
int main()
{
	int* ps = (int*)malloc(100);
	if (ps == NULL)
	{
		perror("malloc:");
	}
	else
	{
		for (int i = 0; i < 50; i++)
		{
			*(ps + i) = i;
		}
		for (int i = 0; i < 50; i++)
		{
			printf("%d ", *(ps + i));
		}
	}
	return 0;
}

分析:

因为我们想要用动态开辟的空间来存整型数据,所以就用整型指针来接受返回值,并且需要强制类型转换,然后用if语句来检验是否开辟成功,若失败,用perror来打印错误信息,若成功,则在后面使用这块空间,对前50个空间赋值为0-50,并打印出来

运行结果:

 但是这还并没有完,因为我们向内存开辟空间用完之后就得还给操作系统,不然的话,这块空间自己不用了,但别人也用不了,还在浪费内存,造成了内存泄漏的问题,这里用free来释放内存

free原型

void free (void* ptr);

 这样来用

free(ps);  //释放内存
ps = NULL;  //将指针置空

因为free(ps)释放内存之后ps这个指针里面仍然还有这块空间的地址,所以我们应该要将ps及时置空,不然后面如果用ps来访问的话,就是非法的

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

calloc

函数原型:

void *calloc( size_t num, size_t size );

参数:

size_t num  这是指定要存放多少个元素

size_t size  指定所要存放元素的每个元素的大小

这个函数会将所开辟的空间自动初始化为0

返回值:void*类型,若开辟成功,返回所开辟空间的地址,开辟失败,返回空指针

头文件:<stdlib.h>

使用:

#include <stdio.h>
#include <stdlib.h>
int main()
{
	int* ps = (int*)calloc(10,sizeof(int));
	if (ps == NULL)
	{
		perror("malloc:");
		return 0;
	}
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", *(ps + i));
	}
	free(ps);
	ps = NULL;
	return 0;
}

realloc

这个函数用来动态调整所开辟的内存大小,realloc函数的出现让动态内存管理更加灵活

函数原型:

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

参数:memblock,要调整的内存的地址

        size,调整之后的大小

返回值:调整之后内存的起始地址void*类型

头文件:<stdlib.h>

使用:

#include <stdio.h>
#include <stdlib.h>
int main()
{
	int* ps = (int*)calloc(10,sizeof(int));
	if (ps == NULL)
	{
		perror("malloc:");
		return 0;
	}
	//调整大小
	int* ptr = (int*)realloc(ps, 20 * sizeof(int));
	if (ptr == NULL)
	{
		perror("realloc");
	}
	else
	{
		ps = ptr;
		ptr = NULL;
	}
	for (int i = 10; i < 20; i++)
	{
		*(ps + i) = i;
	}
	for (int i = 0; i < 20; i++)
	{
		printf("%d ", *(ps + i));
	}
	return 0;
}

以上是关于C语言☀️动态内存管理及相关函数的主要内容,如果未能解决你的问题,请参考以下文章

⭐️欢度国庆-共约C语言进阶⭐️ 动态内存管理+柔性数组 建议收藏

C语言之动态内存管理(动态内存分配+经典笔试题+柔性数组)[建议收藏]

C语言动态内存管理及使用总结篇初学者保姆级福利

C语言动态内存管理以及开辟的注意事项⚠️

动态内存管理

动态内存管理(动态内存函数的介绍,c/c++经典笔试题,柔性数组)