一、动态内存的基本知识
1、申请的动态内存都是堆(一般情况下堆的大小是2G左右)
2、申请动态内存之前首先要引用头文件(# include <stdlib.h>)
3、动态内存使用的函数
malloc: 申请内存函数;
calloc: 内存置0函数;
realloc: 扩充内存函数;
free: 释放内存函数;
4、动态内存的一般语句写法:(以申请内存为例)int *p = (int *)malloc(n*sizeof(int));
5、动态内存存在的问题,内存泄漏(free)。
二、实例应用
1、用筛选法求100以内的素数(malloc)。
分析:筛选法求素数,是将除0和1外其他的数,先除以2,然后将能被2整出的数排除掉,剩下的数再除以3,以此类推。
代码实现:
void SiftPrime(int n)
{
int *p = (int *)malloc(n*sizeof(int));//申请动态内存,(堆,大小一般为2G)
assert(p != NULL);//判断是否为空
if(p == NULL)
{
return ;
}
int i;
for(i=0;i<n;i++)
{
p[i] = 1;//将动态内存中的n个数全部置为1;
}
p[0] = 0;
p[1] = 0;//0和1都不是素数
for(i=2;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
if(j%i == 0)
{
p[j] = 0;//能被2到n-1整除的数置为0;
}
}
}
for(i=0;i<n;i++)
{
if(p[i] == 1)//判断这n个数中是1的数
{
printf("%d\n",i);//只要初值为1的数都是素数。
}
}
free(p);//释放内存
}
int main()
{
SiftPrime(10);
return 0;
}
2、calloc、realloc的用法。
calloc:
int main()
{
int n = 10;
int *p = (int *)malloc(n*sizeof(int));//申请动态内存
for(int i=0;i<10;i++)
{
p[i] = 0;//将内存中每个格子置0
}//等同calloc
int *p = (int *)calloc(n,sizeof(int));//将申请的内存的每个格子都置0
}
realloc:
int main()
{
int n = 10;
int *p = (int *)malloc(n*sizeof(int));
int i;
for(i=0;i<10;i++)//模拟p已经被使用
{
p[i] = i*i + i;
}
int *q = (int *)malloc(20*sizeof(int));//再次申请更大内存
for(i=0;i<10;i++)
{
q[i] = p[i];
}
free(p);
p = q;
q = NULL;
//上面的代码等同于realloc
printf("%d\n",p);
p = (int *)realloc(p,20);//相当于上面用malloc再次申请的更大内存
printf("%d\n",p);
free(p);
return 0;
}
3、内存泄漏问题和free崩溃原因
申请的内存用完之后没必须要释放,也就是没有用free函数,不然不就有可能造成内存泄漏。
free崩溃原因:
a、越界 , b、指针移动,c、重复释放同一段内存,d、释放栈内存
int main()
{
int *p = (int *)malloc(40);
/*for(int i=0;i<40;i++)//a、越界
{
p[i] = 0;
}*/
/*for(int i=0;i<10;i++)//b、指针移动
{
*p = 0;
p++;
}
*/
/*int *q;//c、重复释放同一段内存
q = p;
free(p);
free(q);*/
//int arr[10];
//free(arr);//d、释放栈内存
//free(p);
//int *q = (int *)malloc(80);
//printf("%d,%d\n",p,q);
return 0;
}