1.引言
- 前面我们学习了两种申请空间的方法,一种是直接定义一个数据类型,例如:int n,直接向内存申请四个字节的空间;
第二种是:利用数组开辟一块空间,例如:int arr【10】,向内存申请十个int类型的内存单元。
- 但这两种申请的都是静态内存大小不可改变。接下来学习几个动态内存函数:
2.malloc:
malloc的全称是memory allocation,中文叫动态内存分配,用于申请一块连续的指定大小的内存块区域以void*类型返回分配的内存区域地址.
返回类型为Void*的指针,所以malloc在开辟空间时,并不知道开辟什么类型空间,这需要操作根据实际操作进行强制类型转换。
例如:需要开辟一块40个字节大小的整形类型空间;
利用int*将其强转为int类型,此类函数需要包含一个头文件#include<stdlib.h>.
- 开辟成功:返回一个开辟好空间的指针。
- 开辟失败:返回空指针NULL。
#include<stdio.h> #include<string.h> #include<stdlib.h> int main() { //malloc函数向内存申请空间,无初始值 // void*malloc(size_t size)// int* p = (int*)malloc(40); if (p == NULL) { perror("malloc"); return 1; } for (int i = 0; i < 10; i++) { *(p + i) = i; } for (int i = 0; i < 10; i++) { printf("%d ", *(p + i)); } free(p); p = NULL; return 0; }
运行结果:
3.calloc:
在内存的动态存储区中分配num个长度为size的连续空间,函数返回一个指向分配起始地址的指针;如果分配不成功,返回NULL。
返回类型和malloc一样为Void*的指针,但参数要比malloc 多一个num(数据类型)长度。
例如:需要开辟一块40个字节大小的整形类型空间;
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main() {
//calloc函数含两个参数大小,和类型大小(字节),默认初始值为零//
//void*(size_t num,size_t size)//
int* p = (int*)calloc(10, sizeof(int));
if (p == NULL) {
perror("calloc");
return 1;
}
for (int i = 0; i < 10; i++) {
printf("%d ", *(p + i));
}
free(p);
p = NULL;
return 0;
}
结果:
结果出现了十个零,说明calloc 在开辟空间时有初始值,默认为0,而malloc并没有初始值。
开辟成功与失败的结果和malloc相同。
4.realloc
对已开辟的动态内存大小进行调整,
函数原型:
- ptr:要调整的内存地址。
- size:调整后的新大小。
-
返回值为调整之后的新内存起点。
4.1 realloc调整空间的两种情况。
1.原有空间后还有足够大的空间,接在原有基础上追加空间,原来的空间数据不变。
2.原有空间不够大,在堆区重新找一块合适的空间使用,这样函数返回一个新的地址。
5.free
free: 动态内存释放与回收函数。
函数原型如下:
ptr:开辟空间的返回地址。
空间利用完成后要进行释放,不然很占运行空间,并且要将指针为空,不然会出现很多的野指针,这对代码运行会产生影响。
具体实现如下:
free(p);
p = NULL;
return 0;
1.释放地址空间。
2.将指针值为空。