动态内存函数:malloc、calloc、realloc、free等
使用此函数需要使用#include<stdlib.h>头文件
动态内存:动态创建内存,创建大内存。
1、malloc函数
malloc(n*sizeof(int ))用来分配内存
malloc只管分配内存,并不会初始化,其内存空间中的值可能是随机的。
分配的空间不再使用时,要用free函数释放这块内存空间。
通过例子了解malloc函数
例、求n以内的素数
void SiftPrime(int n)
{
int *p = (int *)malloc(n*sizeof(int));//int p[n];//解决了n的不确定问题
assert(p != NULL);断言
int i;
for(i=0;i<n;i++)
{
p[i] = 1;
}
p[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;
}
}
}
for(i=0;i<n;i++)//打印素数
{
if(p[i] != 0)
{
printf("%d ",i);
}
}
}
int main()
{
SiftPrime(200);
return 0;
}
2、calloc函数
功能:
在内存的动态存储区中分配n个长度为size的连续空间,函数返回一个指向分配起始地址的指针;如果分配不成功,返回NULL。
跟malloc的区别:
calloc在动态分配完内存后,自动初始化该内存空间为零,而malloc不初始化,里边数据是随机的数据。
例:
int main()
{
int *p = (int *)malloc(100*sizeof(int));
for(int i=0;i<100;i++)
{
p[i] = 0;//
//*p = 0;//error
//p++;
}
free(p);//释放内存
return 0;
}
而
int *p = (int *)malloc(100*sizeof(int));
for(int i=0;i<100;i++)
{
p[i] = 0;//
//*p = 0;//error
//p++;
}
这一段可直接用calloc函数写
int *p = (int *)calloc(100,sizeof(int));
但此函数存在问题,使内存泄漏,需要用free函数进行释放
3、realloc函数
功能:更改已经配置的内存空间,即更改由malloc()函数分配的内存空间的大小。
扩大内存:
①如果当前内存段后面有需要的内存空间,则直接扩展这段内存空间,realloc()将返回原指针。
②如果当前内存段后面的空闲字节不够,那么就使用堆中的第一个能够满足这一要求的内存块,将目前的数据复制到新的位置,并将原来的数据块释放掉,返回新的内存块位置。
③如果申请失败,将返回NULL,此时,原来的指针仍然有效。
int main()
{
int *p = (int *)malloc(10*sizeof(int));
printf("%d\n",p);
for(int i=0;i<10;i++)//模拟p被使用
{
p[i] = i;
}
//p = (int *)realloc(p,5*sizeof(int));
//printf("%d\n",p);
//下面等同realloc
/*
int *q = (int *)malloc(20*sizeof(int));
for(int i=0;i<10;i++)
{
q[i] = p[i];
}
free(p);
p = q;
q = NULL;*/
free(p);
return 0;
}
4、free函数
崩溃原因:
①越界
int main()
{
int *p1 = (int *)malloc(20);//这个20是20个字节
for(int i=0;i<20;i++)//而这个20是20个单元格,出现越界
{
p1[i] = 0;
}
free(p1);
return 0;
}
②指针移动
int main()
{
int *p = (int *)malloc(10*sizeof(int));
for(int i=0;i<10;i++)
{
*p = 0;
p++;//使指针移动,使p找不到哪个是它的头
}
free(p);
return 0;
}
③重复释放内存
int main()
{
int *p = (int *)malloc(10*sizeof(int));
int *q = p;
free(p);
free(q);//释放了两次内存
return 0;
}
一个malloc函数对应一个free函数
④释放不是动态创建的内存
int main()
{
int a = 10;
free(&a);
return 0;
}