概念
动态内存申请实际上是在堆区开辟内存空间,而堆区空间手动开辟,手动释放,不像栈区由操作系统自动维护。同时,很多时候我们需要的内存空间取决于实际输入的数据,所以我们就需要动态分配内存了。
动态分配函数
- 注意
动态内存分配函数的使用需要注意以下几点:
- 一般用
memset初始化
- 调用函数后一定要判断一下是否申请成功
- 每次调用函数申请的空间是连续的,但是多次调用函数申请的空间不一定连续。
- 返回的是
void *指针,在调用函数时,需要强制类型转换成我们需要的类型。即-养成调用函数前面接强转的好习惯。
- 内存空间使用完之后一定要释放
,否则会造成内存泄漏。
malloc函数
1 2 3 4 5 6 7 8 9 10 11 12
| #include <stdlib.h> void *malloc(size_t size)
|
- 在堆区中分配一块长度为size字节的连续存储空间;并返回指向该存储空间首地址的指针,分配失败时,返回NULL。
calloc函数
1 2 3 4 5 6 7 8 9 10 11 12 13
| #include <stdlib.h> void *calloc(unsigned int n, size_t size)
|
- 在堆区中分配一块长度为n×size字节的连续存储空间;并返回指向该存储空间首地址的指针;分配失败时,返回NULL。
- 和
malloc只分布内存不负责初始化不同,calloc分配的空间被初始化为0
realloc函数
调用malloc和calloc函数单次申请的内存是连续的,两次申请的两块内存不一定连续。为了满足这种需求,即我先用malloc或者calloc申请了一块内存,我还想在原先内存的基础上挨着申请内存。或者我开始时候使用malloc或calloc申请了一块内存,我想释放后边的一部分未使用的内存。为了解决这个问题,发明了realloc这个函数
1 2 3 4 5 6 7 8 9 10 11 12 13
| #include <stdlib.h> void *realloc(void *ptr, size_t newsize)
|
- 如果传入的指针的内存空间
后面有足够的空间,则直接调整大小,并返回指针;
- 如果传入的指针的内存空间后面没有足够的空间,则重新开辟一块大小为
newsize字节的内存空间,并将原内存空间的内容复制到新内存空间中,并返回新内存空间的指针;
- 如果传入的指针为NULL,则相当于调用
malloc函数;
- 如果
newsize小于传入的指针指向的内存空间,则只调整大小,不改变内容。
free函数
1 2 3 4 5 6 7 8
| #include <stdlib.h> void free(void *ptr)
|
- 释放指针指向的内存空间
ptr必须是malloc、calloc、realloc函数返回的指针,否则结果是未定义的。