当前位置:网站首页>动态内存相关笔记
动态内存相关笔记
2022-07-19 20:30:00 【一般路过半缘君】
C语言中,每次创建一个变量的时候,系统都会自动开辟对应类型字节大小的空间给一个变量,但是这样有时候会不够,于是C语言中又有几种函数,供用户自己申请空间,这就是所谓的动态内存管理,这里我将介绍关于动态内存的函数以及常见错误。
(以下函数都包含着头文件<stdlib.h>中)
void * malloc(size_t size);
第一个函数是malloc函数,该函数会申请一个size大小的字节空间,并且返回这个空间的首地址,但是返回的是一个void* 类型的指针,于是在使用之前需要进行强制转化类型才能整除使用。
void * calloc(size_t num,size_t size);
第二个函数是calloc,与malloc不同,这个函数需要两个参量,第一个参量num表示要开辟的空间个数,而size则表示每个空间的大小,并且calloc函数会将它所开辟的空间全部初始化为0,当然,它也是返回一个void*类型的函数,需要强制类型转换。
void * realloc (void *ptr,size_t size);
这个realloc函数的作业实际上是扩大空间,第一个参数ptr是要调整的空间的首地址,第二个参数size则是要调整到多少个字节,
如
int * p = (int *) malloc(40);
int *pt = (int *)realloc(p,80);
if(pt!=NULL)
p = pt;
这样就将p的空间从40扩大到了80字节了;
但是,realloc开辟的函数实际上是分为两种不同的情况的;
1> 指针后续的空间能够扩大到所需的空间,就直接扩大
2>指针后续的空间不能够扩大到所需的空间,则会在堆区中找一块足够的空间,开辟后,将旧空间的元素放在新空间中,再释放旧空间的内存。
void* free(void *ptr);
之前三个函数都是用来开辟空间的,三个函数所开辟的空间都是在堆区,除非程序关闭,不然内存是不会自动释放的,所以需要有free函数用来将所开辟的空间给释放,否则就会造成内存泄漏等问题。
free函数很简单,所需要的参数就是想释放空间的首地址,不过有一点需要注意的是,free函数虽然能够释放掉空间,但是指针所指向的地址依旧存在,而指针所指向的空间为开辟,这就造成了野指针的问题,因此我们使用free函数释放掉对应空间后,应该是对应指针置为NULL。
如:
int * p = (int *)malloc(40);
if(p!=NULL)
{
free(p);
p = NULL;
}
动态内存常见的错误
在之前的代码段中,我每次开辟空间都会先判断这个指针是否为空,不为空才会使用它,这实际上是因为当malloc calloc realloc三个函数开辟空间失败的时候,会返回一个NULL,而NULL指针是不能用的,所以一定要进行判断再用,而这时动态内存开辟常见错误之一——对NULL指针解引用。
动态内存常见的错误共6种,
1> 对NULL指针解引用
2>对开辟空间越界访问
3>对非动态开辟的空间使用free函数
4>使用free函数释放动态开辟内存的一部分
5>对同一块空间多次释放
6>动态内存开辟忘记释放(内存泄漏)
柔性数组
在C99标准中,结构体允许最后一个成员是一个大小未知的数组,这就是柔性数组成员,
如:
struct S
{
int i;
int a[];
};
在结构体S中,a数组就是一个典型的柔性数组。
柔性数组有以下特点:
1>结构中的柔性数组成员前面必须至少一个其他成员。
2>sizeof 返回的这种结构大小不包括柔性数组的内存。
3>包含柔性数组成员的结构用malloc ()函数进行内存的动态分配,并且分配的内存应该大于结构的大
小,以适应柔性数组的预期大小
柔性数组应该使用malloc来分配它的内存,使用方式如下:
struct S
{
int i;
int a[];
};
int main()
{
struct S* s;
s = (struct S*)malloc(sizeof(struct S)+40);
return 0;
}
这样,这个结构体变量s就分配了44字节的空间,前面4个字节是成员i的空间,后面的数组a被分配了40个字节的空间,但是,实际上在结构体中使用指针类型的变量也能做到类似的事情,但是柔性数组具有自身的便利性,优点如下:
1>方便内存释放
2>有利于访问速度
当然,柔性数组不仅可以使用malloc分配空间,也可以使用realloc来改变空间大小,语法和其他一样。
边栏推荐
- Dest0g3 520迎新赛-web-EasyPHP
- Jincang database kingbasees SQL language reference manual (3.10. database object reference method)
- July 18, 2022, village of p6722 "mcoi-01" in Luogu
- Gson study notes
- 喜讯 | 数睿数据获“2022爱分析·中国低代码最佳实践案例”
- To do difficult work
- Link list of daily Niuke questions
- 现在科技发展背后所呈现出来的是,元宇宙时代的来临
- The LAAS protocol of defi 2.0 is the key to revitalizing the development of defi track
- LVGL 8.2 Roller
猜你喜欢
Data Governance Research Report - data element equity allocation path (2022), 50 Pages pdf
马斯克称已将大脑上传到云端【系统或已开源】
最受IT公司欢迎的 30 款开源软件
2022 National latest fire-fighting facility operator (primary fire-fighting facility operator) simulation questions and answers
适应大众化教育的创客理念设计
Redis log: the killer mace of rapid recovery without fear of downtime
剑指Offer 71:跳台阶扩展问题
VMware solves the problem of not recognizing USB
赴港上市告吹后,土巴兔终止创业板IPO,创始人作出回应
【golang从入门到实践】扑克发牌游戏
随机推荐
指针数组跟数组指针的简单范例
Mysql高级篇学习总结12:索引失效的11种情况
机器人时代发展大趋势对民众的影响
走进创客教育课程实践的真实情境
LVGL 8.2 Message box
串的部分基本操作代码实现
Oracle 里 TCP Socket (KGAS) 这个等待事件一般是什么导致?
Code source du système vidéo court, séquence de chargement des fichiers principaux dans le projet uni app
Redis practice: skillfully use data types to achieve 100 million level data statistics
Skywalking full link monitoring cluster and dynamic deployment
Redis high availability: you call this sentinel sentinel cluster principle
English语法_物主代词
自定义Dialog(包含头尾)
Hbuilderx Eslint配置
Qt的命令行解析
Record the title of the 13th Landbridge cup embedded provincial competition
July 18, 2022, village of p6722 "mcoi-01" in Luogu
请问Redis 如何实现库存扣减操作和防止被超卖?
在公司解决的问题
Data Governance Research Report - data element equity allocation path (2022), 50 Pages pdf