目录
前言
为什么我们需要动态内存分配呢?我们平时所定义的int a[100],是在申明的时候就在栈空间上直接开辟400个字节的空间,这种情况下a可用内存的大小是固定的,如果超过这个范围就是非法访问内存,但是很多情况下我们需要在程序运行时才知道需要多大的空间,比如如果我们预计存1000人的数据,可是实际上来了1500人录入数据,那这多的500人怎么办呢?这里就需要动态内存分配的知识。
1.malloc及free
malloc函数的作用是向内存申请一块连续可用的空间,并将指向这片空间的起始地址的指针返回。内存空间开辟成功返回起始地址的指针,开辟失败则返回NULL。注意:动态内存是在堆区申请。
定义如下:
void* malloc (size_t size);
malloc的返回值是void*也就是任何类型的指针,参数size是指所需要开辟的字节数。
int main()
{
int* a = (int*)malloc(40);
}
这里我们需要将void*强转成int*指针,这样才可以赋给指针变量a,同时也可以表明这片空间是用来存放整型的。
图中框出来的40个字节就是我们为a申请的空间,但这些空间是没有初始值的,从右边的图可以看出来从第十一个元素开始的内存空间就不被允许访问了。
free函数和malloc以及calloc,realloc函数一般是成对出现的,为什么要成对出现?free函数的作用是释放和回收动态内存。你可能很疑惑,之前写程序的时候从来没有听过要释放和回收内存,那为什么动态内存就需要呢?这就涉及到我刚才所提到的动态内存是在堆区上开辟的,而我们以前所用的int a是在栈区上开辟的,在栈区上开辟的空间你进入子函数创建,出子函数就会自动销毁,可是堆区上开辟的空间不一样,如果你不去主动释放和回收它,它会一直占用那片空间,会造成内存泄漏,直到程序结束自动释放。
free函数的定义如下:
void free (void* ptr);
free函数没有返回值,如果ptr指向的空间不是动态开辟的,那么free的行为是未定义的,ptr必须指向的是一片动态开辟空间的首地址。如果ptr=NULL则函数什么都不做。
int main()
{
int* a = (int*)malloc(40);
if (a == NULL)
{
perror("");
return;
}
free(a);
a = NULL;
}
这里free之后将a赋成NULL是因为当动态开辟的空间被释放之后,a就成了一个野指针依旧保留原来的地址,为了防止后续错误调用,导致内存的非法访问。
2.calloc
calloc函数的作用和malloc函数类似
void* calloc (size_t num, size_t size);
calloc函数的作用是开辟num个size字节大小的内存空间并将每个字节初始化为0。
int main()
{
int* a = (int*)calloc(10, sizeof(int));
if (a == NULL)
{
perror("");
return;
}
free(a);
a = NULL;
}
如图所示,这40个字节就是calloc为a开辟的空间,而calloc将所有字节初始化为0,这就是calloc和malloc唯一的区别,同时calloc也要使用free函数释放和回收内存。
3.realloc
realloc函数的作用就是当我们发现最开始申请的动态内存空间大了或者小了的时候,我们可以通过使用realloc函数来调整动态内存空间大小。realloc的定义如下:
void* realloc (void* ptr, size_t size);
ptr指向的是你需要调整的的内存地址,size为调整的总大小,返回的是调整后空间的首地址。
int main()
{
int* a = (int*)calloc(10, sizeof(int));
if (a == NULL)
{
perror("");
return;
}
int* b = realloc(a, 80);
free(b);
b = NULL;
}
如图所示,使用realloc函数将原本40个字节的空间扩大到80个字节,并将开辟的空间地址返回给b。那么到这里大家是否有疑问realloc函数是怎么调整内存大小的呢?b指向的地址是否就是a指向的地址呢?
其实realloc调整动态内存大小的方式有两种:
第一种:当最开始开辟的内存后有足够的空间来调整到所需要的内存大小的时候realloc函数会直接在后面加上需要增加的空间,这个时候的a=b。
第二种:当最开是开辟的空间后没有足够的空间来调整到所需要的内存大小的时候,realloc会在另一个有足够空间的地方开辟空间,同时将原来空间中的数据放到其中,并将原来的内存空间释放掉。
注:以上所有函数都需要在头文件stdlib.h下才能使用。