一.为什么需要动态内存分配
在学习动态内存分配前,我们通常开辟空间的方式有:
1.定义变量;例如:int a=20; //相当于我们在栈空间上开辟了四个字节
2.定义数组;例如:char b[10]={0}; //相当于我们在栈空间上开辟了10个字节的连续空间
但仔细思考下,像这样开辟空间,我们只能开辟固定大小的空间,有时候需要开辟很大的空间,但实际上却只用了一小部分,这样就有很多空间被浪费。虽然我们平时写C的代码不会太长,但如果对于一个大型的项目来说,浪费的空间可能会有严重的影响。所以我们需要动态开辟空间,当我们想要多少的时候,开辟多少的空间,尽可能减少内存的浪费。
二.动态内存函数
1.malloc和free
在C语言中,它为我们提供了这样一个函数malloc:(void* malloc(size_t size));
这个函数通过向内存申请一块连续的空间,并将指向该空间的首地址返回给指针。所以,我们在动态内存开辟的时候,常常是用指针指向,
例如 : int *p=(int*)malloc(40); //开始40个字节的空间
其中函数给出的返回类型是void *,我们这里对他进行了强制类型转换(int *);其开辟空间的结果有两种情况,如果开辟成功,将返回一个指向该空间的指针;如果开辟失败,则返回一个NULL指针。所以我们通常在开辟空间的同时,
要对开辟空间进行判断:(采用上面例子写的指针)
if(p==NULL)//如果开辟失败
{
printf("动态开辟内存失败");
return 0;
}
//如果开辟成功
else ....//
当然,我们开辟了空间,也要回收,不然当电脑想再次用这个空间就用不了了。
所以C语言为我们提供了一个函数free: void free(void* p);
其中p指针是指向的空间是动态开辟的,如果不是指向动态开辟的空间,free函数是未定义的
如果p是空指针,则函数什么都不做。
还有点忘记说了,malloc和free函数都声明在stdlib.h头文件中,需要在main函数前写上。
2.calloc
其实C语言还提供了一个动态开辟内存的函数交calloc: void* calloc(size_t num,size_t size)
其是开辟num个size大小的字节,但和malloc相比,他能将这些开辟的空间初始化为零
3.realloc
当我们开辟了一块空间的时候,有的时候不够用的时候,我们需要额外开辟一块空间
所以就有了realloc函数 : void* realloc(void* p,size_t size)
p是要调整的内存地址,size是调整之后的大小,同样我们额外开辟了空间,也需要用指针来接受,所以他是返回了一个void *是指针。