存储空间的分配和释放
C语言标准库提供四个函数:malloc(),calloc(),realloc(),free(),用来实现内存的动态分配与释放,前三个函数用于动态存储分配,第四个函数用于动态释放。四个函数的头文件都是stdlib.h中。
1.malloc()——动态分配一段内存空间
函数原型:
void *malloc(unsigned int size);
函数功能是在内存动态存储区申请一个长度为size字节的连续存储空间。malloc函数会返回一个指针,并指向所分配存储空间的起始地址。如果没有足够的内存空间分配,则函数返回为空指针NULL。
函数原型的函数值为指针类型,由于基类型为void,如果如果要将这个指针值赋给其他类型的指针变量,需要进行强制类型转换。
例:
(1)申请一个int类型长度的存储空间: int *p=(int *)malloc(sizeof(int));
(2)申请一个结构体类型数据的空间:struct stud *p=(struct stud *)malloc(sizeof(stud));
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *p=(int *)malloc(sizeof(int));
*p=100;
printf("%d\n",*p);
return 0;
}
2.calloc()——动态分配连续内存空间
函数原型:
void *calloc(unsigned int n,unsigned int size);
函数功能是在内存申请n个长度为size字节的存储空间,并返回该存储空间的起始地址。如果没有足够的内存空间分配,则函数返回为空指针NULL。
函数原型的函数值为指针类型,由于基类型为void,如果如果要将这个指针值赋给其他类型的指针变量,需要进行强制类型转换。
例如:申请10个int类型长度的存储空间: int *p=(int *)calloc(10,sizeof(int));然后将分配到的存储空间地址转换为int类型地址,将其首地址赋给所定义的指针变量p。此后就可以用p作为10个整型元素数组使用,此数组没有数组名,只能用指针变量p来访问。
同样也可以用malloc函数实现:int *p=(int *)malloc(sizeof(int)*10);
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *p=(int *)calloc(10,sizeof(int));
for(int i=0;i<10;i++)
{
*(p+i)=i;
// p[i]=i;
}
for(int i=0;i<10;i++)
{
printf("%d ",*(p+i));
//printf("%d ",p[i]);
}
return 0;
}
//0 1 2 3 4 5 6 7 8 9
3.realloc()——改变指针指向空间大小
函数原型:
void *realloc(void *ptr,size_t size);
函数功能是改变ptr指针指向大小为size的空间。size大小设置可以任意。返回值是一个只向新地址的指针。如果出现错误,则返回NULL。
函数原型的函数值为指针类型,由于基类型为void,如果如果要将这个指针值赋给其他类型的指针变量,需要进行强制类型转换。
例如:
int *p=(int *)malloc(sizeof(int)*10);
short *r=(p,sizeof(short));
其中,p是指向分配的整型空间,然后使用realloc函数改变p指向空间的大小,其大小设置为短整型,然后将改变后的内存空间的地址返回赋值给r指针。
#include <stdio.h>
#include <stdlib.h>
int main()
{
short *r;
double *p=(double *)malloc(sizeof(double));
printf("指针p指向内存空间的起始地址: %d \n",p);
printf("指针p指向内存空间大小: %d \n",sizeof(*p));
r=(short *)realloc(p,sizeof(short));
printf("指针r指向内存空间的起始地址: %d \n",r);
printf("指针r指向内存空间大小: %d \n",sizeof(*r));
return 0;
}
/*
指针p指向内存空间的起始地址: 34189328
指针p指向内存空间大小: 8
指针r指向内存空间的起始地址: 34189328
指针r指向内存空间大小: 2
*/
4.free()——释放存储空间
函数原型:
void free(void *p);
函数功能是将指针变量p指向的存储空间释放,交还给系统。free函数没有返回值(p只能是程序中此前最后一次调用malloc或calloc函数所返回的地址)。
例如:
int *p,*q=(int *)calloc(10,sizeof(int));
p=q;
q++;
free(p);//将p指向的,此前调用了calloc函数申请的存储空间释放
如果改用free(q)则会提示错误,因为执行了q++;q已改变。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *p=(int *)malloc(sizeof(int));
*p=100;
printf("%d ",*p);
free(p);
printf("%d ",*p);
return 0;
}
//100 随机数
本例子中,定义指针p指向动态分配的内存空间,使用新空间保存数据,然后利用指针进行输出。接着调用了free函数将其空间释放,当在输出时,因为保存数据的空间已经被释放,那么数据也就不存在了,此时输出的就是一个不可预料的值。