一、为什么存在动态内存分配
常见的创建变量和数组开辟空间的大小是固定的,且数组在声明过程中必须指定数组长度,它所需要的内存在编译时分配。但有时我们需要的空间大小在程序运行时才知道,因此我们需要内存的动态开辟。
二、动态内存函数的介绍
2.1 malloc和free
malloc函数可开辟动态内存,申请一块连续可用的空间,并返回指向开辟好空间的指针。
- void* malloc (size_t size)大小单位是字节。
- 若开辟成功,则返回指向空间的指针。
- 若开辟失败,则返回NULL指针,因此开辟后必须使用perror函数检查。
- 若size为0,malloc的行为是标准未定义的,取决于编译器。
注:malloc不会初始化内存
free函数是用来释放动态开辟的内存。
- 若内存不是动态开辟的,则free的行为是未定义的。
- 若参数ptr是NULL指针,则函数什么也不做。
注:1.malloc和free均包含在stdlib.h中
2.malloc与free成对出现,否则会造成内存泄漏,并且需及时将ptr指针置空,否则可能造成野指针非法访问。
2.2 calloc
void* calloc(size_t num,size_t size)将num个大小为size的元素开辟一块空间,且初始化每个字节为0.
2.3 realloc(此函数最为重要,可灵活地开辟内存大小)
void * realloc (void ptr ,size_t size);
- ptr是要调整的内存地址
- size是调整之后的总大小
- 返回值为调整之后的起始地址
- 若ptr == NULL,则相当于malloc函数
- realloc在调整内存空间时有2种情况
1.原有空间后有足够大的空间
2.原有空间之后,没有足够大小,则会在堆空间中找另外一个合适大小的连续空间,将旧空间内容拷贝放到新空间内,同时释放掉旧的空间。
三.常见的动态内存错误
- 对NULL指针的解引用
- 对动态开辟空间的越界访问
越界访问一般不会报错,因为动态开辟的空间只有起始和末尾设置几个字节的“检查位”来检查越界,检查位只有在程序结束或free释放空间时被触发。一般报错时与free里的参数无关,应调试观察数组是否越界。
- 对非动态开辟空间使用free释放
- 使用free释放动态开辟空间的一部分
- 对同一动态内存多次释放
- 动态开辟内存忘记释放