点击蓝字
关注我们
1.当前我们知道的内存的使用方法
2.为什么存在动态内存分配
如上我们已学的开辟空间的方式有两个特点:
空间开辟的大小是固定的
必须指定数组的长度
所以就产生了空间开大了浪费开小了不够用的问题,所以使用动态内存分配
3.动态内存函数
(1)malloc 和 free
a.malloc函数
malloc函数向内存申请一块连续可用的空间,并返回指向这块空间的指针。
如果开辟成功,返回一个指向开辟好空间的指针
如果开辟失败,返回一个NULL指针,因此malloc的返回值一定要做检查
b. free函数
free函数用来释放动态开辟的内存
如果参数p指向的空间不是动态开辟的(eg:数组),那free函数的行为是未定义的;
如果参数p是NULL指针,则函数什么事都不用做;
c.举例说明malloc函数和free函数如何使用
开辟10个整形大小的空间,并将0-9放入
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{//向内存申请10个整形的空间int* p = (int*)malloc(10 * sizeof(int));//开辟空间失败,打印失败原因if (p == NULL){//errno:Last error numberprintf("%s\n", strerror(errno));}//开辟空间成功,将0-9放入else{for (int i = 0; i < 10; i++){*(p + i) = i;}for (int i = 0; i < 10; i++){printf("%d ", *(p + i));}}//释放掉p指向的这段空间,但是指针p还是指向这段空间free(p);//防止野指针,需要将指针制空p = NULL;return 0;
}
输出:
开辟空间失败,并打印开辟失败原因
INT_MAX 整形最大–>可右键转到定义查看
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{//向内存申请10个整形的空间int* p = (int*)malloc(INT_MAX);//开辟空间失败,打印失败原因if (p == NULL){//errno:Last error numberprintf("%s\n", strerror(errno));}//开辟空间成功,将0-9放入else{for (int i = 0; i < 10; i++){*(p + i) = i;}for (int i = 0; i < 10; i++){printf("%d ", *(p + i));}}//释放掉p指向的这段空间,但是指针p还是指向这段空间free(p);//防止野指针,需要将指针制空p = NULL;return 0;
}
(2)calloc
a. calloc函数
calloc函数的功能是为num个大小为size的元素开辟一块空间,并且把空间的每个字节初始化为0
calloc和malloc的区别在于calloc会在返回地址之前把申请的空间的每个字节初始化为0
b.举例说明calloc函数如何使用
开辟10个整形大小的空间并初始化为0
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{int* p = (int*)calloc(10, sizeof(int));if (p == NULL){printf("%s\n", strerror(errno));}else{for (int i = 0; i < 10; i++){printf("%d ", *(p + i));}}free(p);p = NULL;return 0;
}
(3)realloc
a. realloc函数
p是要调整的内存地址
size是调整之后的大小
返回值为调整之后的内存起始位置
b.realloc在调整内存空间存在的两种情况:
情况1:原有空间之后有足够大的空间
如果p指向的空间之后有足够的内存空间可以追加,则直接追加,然后返回p
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{int* p = (int*)malloc(20);if (p == NULL){printf("%s\n", strerror(errno));}else{for (int i = 0; i < 5; i++){*(p + i) = i;}}//得用一个新的变量来接受realloc函数的返回值//防止开辟失败返回NULL给p找不到之前的空间int*ptr = (int*)realloc(p,40);if (ptr != NULL){p = ptr;for (int i = 5; i < 10; i++){*(p + i) = i;}for (int i = 0; i < 10; i++){printf("%d ", *(p + i));}}free(p);p = NULL;return 0;
}
情况2:原有空间之后没有足够大的空间
如果p指向的空间之后没有足够大的内存空间可以追加,则realloc函数会重新找一块新的内存区域,开辟一块满足需求的空间,并把原来内存中的数据拷贝到新的空间,释放旧的内存空间,最后返回新开辟的内存空间地址
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{int* p = (int*)malloc(20);if (p == NULL){printf("%s\n", strerror(errno));}else{for (int i = 0; i < 5; i++){*(p + i) = i;}}//得用一个新的变量来接受realloc函数的返回值//防止开辟失败返回NULL给p找不到之前的空间int*ptr = (int*)realloc(p,4000);if (ptr != NULL){p = ptr;for (int i = 5; i < 10; i++){*(p + i) = i;}for (int i = 0; i < 10; i++){printf("%d ", *(p + i));}}free(p);p = NULL;return 0;
}
注意:得用一个新的变量来接受realloc函数的返回值,防止开辟失败返回NULL给p找不到之前的空间
如果你年满18周岁以上,又觉得学【C语言】太难?想尝试其他编程语言,那么我推荐你学Python,现有价值499元Python零基础课程限时免费领取,限10个名额!
▲扫描二维码-免费领取
戳“阅读原文”我们一起进步