动态内存概述
所谓动态内存其实是相对于静态内存而言的,在C语言中如果我们要开辟一个十个整型的空间,一般使用的就是传统数组的方法。但传统数组存在几个明显的缺点:
1.数组的长度必须事先给定,且只能是常量不能是变量:
test1()
{
int i = 5;
int arr[i];//错误
int arr[5];//正确
}
正因如此数组的长度不能在函数运行的过程当中动态地扩充和缩小。
2.传统数组的内存,程序员无法手动释放。因此在该函数运行期间,系统为该数组分配的空间一直存在,直到函数运行完毕数组的空间才会自动释放
3.在一个函数定义的数组,只能在该函数运行期间被其他函数使用,但该函数运行完毕,其他函数就无法再使用。
动态内存的使用
动态内存的实现是靠malloc,calloc,realloc,free四个函数实现的。
malloc函数,free函数
void *malloc( size_t size );
malloc 是一个库函数,头文件为<stdlib.h>
从以上知道malloc只有一个类型为整型的形参,其返回值为void*空指针。其 形参的表示我们所想要开辟的是多少字节的空间,如果形参是四十即表示我们要开辟一个大小为四十字节的空间。malloc返回的是指向我们所开辟空间首元素的地址,如果我们开辟的是十个整型空间,那么就要使其返回值强制类型转换为整型 指针(int*),同理如果是其他类型就强转为所对应的类型。
#include <stdlib.h>
int main()
{
int* p = (int* )malloc(40);
//开辟了十个整型的空间
return 0;
}
我们把所要开辟空间的首元素地址赋值给了p指针,那么就可以通过p指针存放我们想要分配的数据。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
int main()
{
int* p = (int* )malloc(40);
if (p == NULL)//内存不足或函数未能成功执行,返回空指针
{
printf("%s\n", streror(errno));
return 1;
}
int i = 0;
for (i = 0;i<10;i++)
{
*(p + i) = i;//赋值
}
for (i = 0; i < 10; i++)
{
printf("%d\n", *(p + i));//输出
}
free(p);
p = NULL;
return 0;
}
void free( void *memblock );
free函数,主动释放malloc所开辟的内存空间。但malloc开辟的内存空间释放完毕后,原来p指针所指向的地址仍然是原地址
int main()
{
int* p = (int*)malloc(4);
*p = 10;
printf("%p\n", p);
free(p);
printf("%p\n", p);
}
输出的为相同的地址。因此我们需要在free函数使用后给原先的指针变量置为空指针(NULL)。
calloc函数
void *calloc( size_t num, size_t size );
calloc函数和malloc函数并没有本质的区别。calloc与malloc函数不同的地方是在calloc函数开辟内存空间时将已分配的内存空间初始化为0
realloc函数
void *realloc( void *memblock, size_t size );
当我们所需要的存储的数据,malloc函数开辟的空间内存不够时,我们就需要使用realloc函数进行扩容。
int main()
{
int* p = (int* )malloc(40);
if (p == NULL)
{
printf("%s\n", streror(errno));
return 1;
}
int i = 0;
for (i = 0;i<10;i++)
{
*(p + i) = i;
}
for (i = 0; i < 10; i++)
{
printf("%d\n", *(p + i));
}
realloc(p, 80);//将malloc所开辟的内存空间扩容至80字节
free(p);
p = NULL;
return 0;
}