在开始之前,给大家介绍一下内存空间
一、动态内存函数介绍
malloc
函数原型:void* malloc (size_t size)
函数介绍:可以在堆区申请一块空间,参数是要申请的字节数,返回的类型是空指针,申请失败后会返回空指针,申请成功会返回申请空间的首地址
int main()
{
int*p=(int*)malloc(sizeof(int)*5);
//因为返回的是void类型指针,要使用就得强转成我们需要的类型
if(p==NULL)//注意这里需要判断申请是否成功,虽然大部分情况是能成功的
{
printf("malloc fail!\n");
return 0;
}
int i=0;
//对申请的空间的使用与正常的指针的使用一样
//注意:不要随意改变p指针的值,当空间用完,需要释放,而释放需要使用申请空间的首地址
for(i=0;i<5;i++)
{
p[i]=i;
}
free(p);//释放指针
return 0;
}
free
函数原型:void free (void* ptr);
函数介绍:用来释放动态申请的空间,函数的参数是申请空间的首地址
注意:1. free只能释放动态开辟的空间
2. 当指针为NULL时,free函数啥也不干
calloc
函数原型:void* calloc (size_t num, size_t size)
函数介绍:与malloc作用相同,只是calloc的参数有两个,第一个是元素个数,第二个是元素的大小,并且calloc会将申请到的空间全部赋值为0,malloc申请的空间是随机值
realloc
函数原型:void* realloc (void* ptr, size_t size)
函数介绍:可以调整动态开辟内存的大小,第一个参数是要修改的动态申请空间的地址,第二个参数是修改后需要的空间大小
注意:1.第一个参数为空指针时,该函数的作用和malloc函数一样
2.当动态申请空间之后的空间足够时,该函数会将之后的空间交给你,当申请空间之后的空间不足够时,该函数会在其他地方申请空间,并将之前开辟空间的内容,拷贝过来,当然之前的空间会被释放
int main()
{
int* p = (int*)malloc(sizeof(int) * 5);
int* tmp = (int*)realloc(p,sizeof(int)*10);
//注意动态申请的内存都有可能失败,要做好判断
//int* p = (int*)realloc(p,sizeof(int)*10);
//这里注意不能用上面的写法,如果返回NULL,那么我们将无法找到之前开辟的空间,就无法释放,会造成内存泄漏
if (tmp == NULL)
{
printf("realloc fail!\n");
return 0;
}
p = tmp;
return 0;
}
二、常见的动态内存的错误
1.对NULL指针的解引用操作
2.对动态开辟空间的越界访问
3.对非动态开辟内存使用free释放
4.使用free释放一块动态开辟内存的一部分
5.对同一块动态内存多次释放
6.动态开辟内存忘记释放(内存泄漏)