通过动态内存管理实现在VS2022中实现变长数组

目录

一、malloc函数和free函数

二、calloc函数

 三、realloc函数


    不知道大家在使用vs2022编译器时有没有遇见过这样一个问题,当我们用一个变量来作为数组的大小时,编译器会报错,要求我们使用常量,这样一来就会使我们的内存空间被大量浪费,使我们非常的头疼,但是如果当我们学到动态内存管理时,我们就有了解决这个问题的办法。

一、malloc函数和free函数

C 语言提供了一个动态内存开辟的函数:
void* malloc (size_t size);
        这个函数向内存申请一块连续可用的空间,并返回指向这块空间的指针。
如果开辟成功,则返回一个指向开辟好空间的指针。
如果开辟失败,则返回一个NULL指针,因此malloc的返回值一定要做检查。
返回值的类型是 void* ,所以malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自己 来决定。 如果参数 size 0malloc的行为是标准是未定义的,取决于编译器。
        malloc函数可以开辟一块指定大小的内存空间,并返回指向这个空间最开始的指针,但是值得注意的是,返回指针的类型是void* 所以我们在使用之前,要强制类型转换为我们要使用的
int* pa = (int*)malloc(40);  // 开辟一个40字节大小的内存空间,并转换为整型

        注意:当内存空间开辟失败,会返回一个空指针,所以我们在使用之前应该先对指针是否为空进行检查。

下面给出一个使用案例,打印从1~10数字。

int main()
{
	int* p = (int*)malloc(40);
	if (p == NULL)                         // 判断是否为空指针
	{
		printf("%s\n", strerror(errno));
		return 1;
	}
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		*(p + i) = i + 1;
		printf("%d ",*(p + i));
	}
	free(p);
	p = NULL;
	return 0;
}

        当我们使用完开辟的空间,不需要了以后,我们要主动将内存释放出来,否则在一个大型项目中例如 7 * 24小时运转的项目,整个程序最终会因为内存不断被蚕食而崩溃,所以我们就需要使用free函数。如上,只需要将需要释放的内存的指针传给free函数,我们就可以释放它的内存。

学到这里,我们就可以实现变长数组的模拟了

int main()
{
	int n = 0;
	printf("请输入数组的长度:> ");
	scanf("%d",&n);
	int* pa = (int*)malloc(n * sizeof(int));
	if (pa != NULL)
	{
		int i = 0;
		for (i = 0; i < n; i++)
		{
			printf("请输入数组中的数字:> ");
			int input = 0;
			scanf("%d",&input);
			*(pa + i) = input;
		}
		for (i = 0; i < n; i++)
		{
			printf("%d ",*(pa + i));
		}
	}
	else
	{
		printf("%s\n",strerror(errno));
	}
	free(pa);
	pa = NULL;
	return 0;
}

二、calloc函数

        与malloc相似,calloc函数也可以开辟一块内存空间,但是与malloc不同的是,calloc不仅开辟空间,并且会初始化为0。

        函数的功能是为 num 个大小为 size 的元素开辟一块空间,并且把空间的每个字节初始化为0。 与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全0

举个例子:
#include 
#include 
int main()
{
 int *p = (int*)calloc(10, sizeof(int));
 if(NULL != p)
 {
     // 使用空间
 }
 free(p);
 p = NULL;
 return 0;
}

下面我们使用calloc来模拟变长数组


// 使用calloc


int main()
{
	int n = 0;
	printf("请输入数组中元素个数:> ");
	scanf("%d",&n);

	int* p = (int*)calloc(n,sizeof(int));
	if (p != NULL)
	{
		int i = 0;
		printf("请输入数组中的元素:> ");
		for (i = 0; i < n; i++)
		{
			int input = 0;
			scanf("%d",p + i);
		}
		for (i = 0; i < n; i++)
		{
			printf("%d ",*(p + i));
		}
	}
	free(p);
	p = NULL;
 	return 0;
}

 三、realloc函数

realloc函数的出现让动态内存管理更加灵活。
有时会我们发现过去申请的空间太小了,有时候我们又会觉得申请的空间过大了,那为了合理的时
候内存,我们一定会对内存的大小做灵活的调整。那 realloc 函数就可以做到对动态开辟内存大小
的调整。
函数原型如下:
void* realloc (void* ptr, size_t size);
ptr 是要调整的内存地址
size 调整之后新大小
返回值为调整之后的内存起始位置。
这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到的空间
realloc函数调整内存空间有两种情况,请看下图
通过动态内存管理实现在VS2022中实现变长数组_第1张图片

        由此可知,当后续空间不够扩展时,realloc函数会将原有的内存空间释放掉,重新开辟一块完整的内存空间,所以,我们不可以用原来的指针来接收realloc的返回值。

 除此之外,值得注意的是,当我们给realloc函数传一个空指针时,realloc函数的功能就与malloc函数类似,它会在开辟一块新的指定大小的内存空间,并将内存空间的指针返回来。

参考资料来自   www.cplusplus.com

通过动态内存管理实现在VS2022中实现变长数组_第2张图片

通过动态内存管理实现在VS2022中实现变长数组_第3张图片

以上就是动态内存管理的所有基础知识,感谢各位的观看 

  

你可能感兴趣的:(开发语言,c语言,数据结构,算法)