博客
关于我
为什么存在动态内存分配,动态内存函数(malloc函数,free函数,calloc函数,realloc函数)
阅读量:111 次
发布时间:2019-02-26

本文共 3209 字,大约阅读时间需要 10 分钟。

目录:

1.当前我们知道的内存的使用方法

在这里插入图片描述

2.为什么存在动态内存分配

如上我们已学的开辟空间的方式有两个特点:

(1) 空间开辟的大小是固定的
(2) 必须指定数组的长度
所以就产生了空间开大了浪费开小了不够用的问题,所以使用动态内存分配

3.动态内存函数

3.1 malloc 和 free

(1) malloc函数

在这里插入图片描述

malloc函数向内存申请一块连续可用的空间,并返回指向这块空间的指针。
• 如果开辟成功,返回一个指向开辟好空间的指针
• 如果开辟失败,返回一个NULL指针,因此malloc的返回值一定要做检查

(2) free函数

在这里插入图片描述

free函数用来释放动态开辟的内存
• 如果参数p指向的空间不是动态开辟的(eg:数组),那free函数的行为是未定义的;
• 如果参数p是NULL指针,则函数什么事都不用做;

(3) 举例说明malloc函数和free函数如何使用

a. 开辟10个整形大小的空间,并将0-9放入

#define _CRT_SECURE_NO_WARNINGS#include
#include
#include
int main(){ //向内存申请10个整形的空间 int* p = (int*)malloc(10 * sizeof(int)); //开辟空间失败,打印失败原因 if (p == NULL) { //errno:Last error number printf("%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;}

在这里插入图片描述

b. 开辟空间失败,并打印开辟失败原因

• INT_MAX 整形最大–>可右键转到定义查看

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS#include
#include
#include
int main(){ //向内存申请10个整形的空间 int* p = (int*)malloc(INT_MAX); //开辟空间失败,打印失败原因 if (p == NULL) { //errno:Last error number printf("%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;}

在这里插入图片描述

3.2 calloc

(1) calloc函数

在这里插入图片描述

• calloc函数的功能是为num个大小为size的元素开辟一块空间,并且把空间的每个字节初始化为0
• calloc和malloc的区别在于calloc会在返回地址之前把申请的空间的每个字节初始化为0

(3) 举例说明calloc函数如何使用

a.开辟10个整形大小的空间并初始化为0

#include
#include
#include
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.3 realloc

(1) realloc函数

在这里插入图片描述

• p是要调整的内存地址
• size是调整之后的大小
• 返回值为调整之后的内存起始位置

(2)realloc在调整内存空间存在的两种情况:

• 情况1:原有空间之后有足够大的空间

如果p指向的空间之后有足够的内存空间可以追加,则直接追加,然后返回p

在这里插入图片描述

#include
#include
#include
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
#include
#include
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找不到之前的空间

转载地址:http://kpdz.baihongyu.com/

你可能感兴趣的文章
MySQL 数据库设计总结
查看>>
Mysql 数据库重置ID排序
查看>>
Mysql 数据类型一日期
查看>>
MySQL 数据类型和属性
查看>>
mysql 敲错命令 想取消怎么办?
查看>>
Mysql 整形列的字节与存储范围
查看>>
mysql 断电数据损坏,无法启动
查看>>
MySQL 日期时间类型的选择
查看>>
Mysql 时间操作(当天,昨天,7天,30天,半年,全年,季度)
查看>>
MySQL 是如何加锁的?
查看>>
MySQL 是怎样运行的 - InnoDB数据页结构
查看>>
mysql 更新子表_mysql 在update中实现子查询的方式
查看>>
MySQL 有什么优点?
查看>>
mysql 权限整理记录
查看>>
mysql 权限登录问题:ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: YES)
查看>>
MYSQL 查看最大连接数和修改最大连接数
查看>>
MySQL 查看有哪些表
查看>>
mysql 查看锁_阿里/美团/字节面试官必问的Mysql锁机制,你真的明白吗
查看>>
MySql 查询以逗号分隔的字符串的方法(正则)
查看>>
MySQL 查询优化:提速查询效率的13大秘籍(避免使用SELECT 、分页查询的优化、合理使用连接、子查询的优化)(上)
查看>>