动态内存

本文详细介绍了C语言中动态内存管理的基本概念和技术,包括malloc()、free()、calloc()和realloc()函数的使用方法及注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       在写代码的时候我们常常遇到这样的问题,在开始定义了内存空间来存储所使用的数,比如 int arr[5] ,有时写到最后我们所定义的内存空间不够用,超出所定义的内存大小,或者我们所定义的内存空间太大了,占用太多的空间,那么有没有一种方法能使我们所定义的空间内存刚刚用户完,即不超出,也不浪费。

1. malloc()函数和free()函数

   我们在开辟内存空间时,使用动态内存来开辟,要在头文件中加入stdlib.h文件(内存区域在堆里面)

int *p=(int *)malloc(n * sizeof(int))//相当于int p[n]

        在这个程序中,首先开辟了n个int类型的空间,然后把p指向这个空间的位置。在这里的指针是指向第一个int值。并不是我们全部开辟的n个int的空间。这就和数组一样,指向数组的指针式指向数组首元素的地址,并不是整个数组的元素。所以,在这里我们的操作也和数组是一样的,p[0]就是第一个元素,p[1]就是第二个元素。

eg:找出1~20之间的所有素数并且输出 

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <malloc.h> 
void SiftPrime(int n)
{
	int *p = (int *)malloc(n*sizeof(int));//等同int p[n];
	assert(p != NULL);//加断言,判断p不能为空 
	if(p == NULL)
	{
		return ;
	}
	int i;
	for(i=0;i<n;i++)
	{
		p[i] = 1;
	}
	p[0] = p[1] = 0;
	for(i=2;i<n;i++)
	{
		for(int j=i+1;j<n;j++)
		{
			if(j%i == 0)
			{
				p[j] = 0;
			}
		}
	}
	for(i=0;i<n;i++)
	{
		if(p[i] != 0)
		{
			printf("%d\n",i);
		}
	}
}
int main()
{
	SiftPrime(20);
	return 0;
}

    当我们使用malloc()开辟完内存空间以后,我们所要考虑的就是释放内存空间,在这里,C给我们提供了free()函数。free()的参数就是malloc()函数所返回的地址,释放先前malloc()函数所开辟的空间。  对于上面我们所开辟的空间进行释放,那么我们就可在最后加上一句   free(p),释放 申请的动态内存,如果不释放,将会造成内存泄露。

2.free()的重要性

    free()函数在动态内存中使用比较多,但是在使用的时候经常会出现崩溃问题,主要的崩溃方面有以下:

       1.越界,漏泄sizeof,realioc(下面会讲到这个函数)第二个参数写错

int main()//free崩溃情景1
{
	int *p = (int *)malloc(10*sizeof(int));
	for(int i=0;i<=10;i++)//越界
	{
		p[i] = 0;
	}
	free(p);
	return 0;
}

     2. 修改了指针的指向

int main()//free崩溃情景2
{
	int *p = (int *)malloc(10*sizeof(int));
	for(int i=0;i<10;i++)
	{
		*p = 0;
		p++;//修改了指针的指向
	}
	free(p);
	return 0;
}

3.  重复释放同一段内存

int main()//free崩溃情景3
{
	int *p = (int *)malloc(10*sizeof(int));
	for(int i=0;i<10;i++)
	{
		p[i] = i;
	}
	int *q = (int *)malloc(20*sizeof(int));
	for(int i=0;i<10;i++)
	{
		q[i] = p[i];
	}
	free(p);
	p = q;
	///////////////
	free(p);
	free(q);重复释放
	return 0;
}
4.释放非动态内存   
int main()//情景4
{
	int arr[10];//非动态内存
	free(arr);
        return 0;
}

3.calloc()函数和realloc()函数

        在了解calloc之前,我想先写一道题,申请一段10个大小的动态内存,并且让10个数输出,都赋值为0           

int main()
{
	
	int *arr = (int *)malloc(10*sizeof(int));
	for(int i=0;i<10;i++)
	{
		arr[i] = 0;
		printf("%d ",arr[i]);
	}
	return 0;
}

那么为了方便一句话写出,那么就可以使用calloc()函数来写

int main()
{
	int *arr = (int *)calloc(10,sizeof(int));//0,0,0,00,
	for(int i=0;i<10;i++)
        printf("%d ",*arr);
	return 0;
}

       通过上面的例子,我们可以知道calloc()函数有两个参数,并且这两个函数都是size_t类型(unsigned int类型)的数。第一个参数在这里所说的是所需要开辟的内存单元数量,第二个参数是每个单元的字节的大小。

        realloc()函数用来修改一个原先已经分配的内存的大小。使用这个函数,你可以让一块内存增大还是缩小。当扩大时,这块内存原先的内容会依然保留,新增加的添加到原先的后面。缩小时,该内存的尾部部分内存去掉,剩余保留。

注意:对于realloc()函数,如果原先的内存无法修改,这时候realloc()函数再会分配一块内存,并且把原先那块内存的内容复制到上面去。所以,使用了realloc函数以后,你这时候在使用的就该是realloc函数返回的新指针了。当realloc函数的第一个参数是NULL时,这时候我们可以把它当作是malloc()函数。

#include <stdio.h>
#include <stdlib.h>
int main()
{
	int *p = (int *)malloc(10*sizeof(int));
	int i;//模拟p被使用
	for(i=0;i<10;i++)
	{
		p[i] = 10*i;
	}
	printf("%d\n",p);
	p = (int *)realloc(p,10*sizeof(int));
	printf("%d\n",p);
	free(p);
	printf("%d\n",p);//释放后不为空
	/*//下面的代码等同realloc
	int *q = (int *)malloc(20*sizeof(int));//在原来的基础上再开辟10个空间 
	for(i=0;i<10;i++)
	{
		q[i] = p[i];
	}
	p = q;
	q = NULL;*/
	return 0;
}
才开始学C,有写的不对的地方,希望各位大神能多指导指导。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值