目录
基本概念
什么是动态内存开辟
动态内存开辟,指的是从堆上面申请指定大小的空间。
那什么又是堆呢,堆是由内存分配的一块空间 ,这块空间就被用于动态内存申请。
用一个类比来说明一下堆空间
- 栈空间由我们的编译器帮助我们开辟和释放,调用函数时开辟空间,返回函数时释放空间。
- 堆空间由我们自己手动来开辟和释放。
为什么要用去堆区申请空间
因为程序员对堆区空间的控制更灵活。
- 堆区可以申请指定大小的空间,在后续使用时可以对已经申请的空间经行扩容与缩容
- 在需要时可以去申请空间,不需要时可以对该空间经行释放
如何使用从堆区申请空间
由库函数来帮助我们申请、扩缩容以及释放空间,我们只需要学习库函数的使用。
动态内存开辟函数一共有四个,分别是malloc,calloc,free,fealloc。
- malloc与calloc是用来开辟空间,以返回值的形式来接受该空间的起始的地址,calloc区别与malloc的是它会将返回的空间全部初始化为0
- fealloc是用来扩缩容空间的
- free是用来将空间返回给堆区的
下面的内容就是动态内存函数的详细介绍
malloc函数介绍
malloc函数用于从存堆上申请一块指定大小的空间,以返回的形式返回一个指向该空间的指针
函数的申明:
void* malloc (size_t size);
实现功能:
向堆区申请一块连续的空间,并返回指向该空间起始地址的指针
参数:
参数1,申请空间的大小单位是字节
返回值:
- 如果申请空间成功,会返回一个指向该空间起始地址的指针
- 如果申请空间失败,会返回NULL(空指针)
使用:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* pa = (int*)malloc( sizeof(int)*10 );//申请一块40字节的空间
if (pa == NULL)//如果开辟空间失败就提示一下
{
perror("开辟空间失败,原因是");
}
else
{
int i = 0;
//存储1到10并打印到屏幕上
for (i = 0; i < 10; i++)
{
*(pa + i) = i+1;
printf("%d ", *(pa + i));
}
free(pa);//将该空间释放掉
}
return 0;
}
使用细节
- malloc并不会对返回空间内容经行初始化
- size参数如果小于1,malloc的行为是标准未定义的,取决于编译器
- malloc返回的是void类型的指针,所以接收返回值时需要进行强制类型转换
- 有可能会开辟空间失败,所以一般使用的时候会检查malloc的返回值是否为空指针
free()函数介绍
释放掉动态函数开辟的空间
函数申明:
void free (void* ptr);
实现功能:
将动态申请的空间返还给堆区
参数:
参数1,指针指向那个要被释放的动态空间
返回值:
空
使用:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* pa = (int*)malloc( sizeof(int)*10 );//申请一块40字节的空间
free(pa); //将该空间释放掉
pa = NULL; 让pa指向空
return 0;
}
使用细节
- 如果不对动态开辟的空间经行释放可能会造成内存泄漏
- 它释放掉的空间必须是动态开辟的
- 不能重复释放同一块动态开辟的空间
- free的参数必须是动态内存的起始地址,如:
void test() { int *p = (int *)malloc(100); p++; free(p); //p不在指向动态内存的起始地址 }
- 建议将指向已被释放地址的指针赋值为空指针,避免非法访问
- 如果free参数是空指针则什么也不做