呼伦贝尔网站建设厦门网站建设报价

news/2025/9/23 16:10:59/文章来源:
呼伦贝尔网站建设,厦门网站建设报价,网站建设及维护服务器,手机网站欣赏动态内存管理 1. 为什么存在动态内存管理2. 动态内存函数的介绍2.1 malloc函数和free函数2.2 calloc函数2.3 realloc函数 3. 常见的动态内存错误3.1 对NULL指针的解引用操作3.2 对动态开辟空间的越界访问3.3 对非动态开辟内存使用free函数3.4 使用free释放动态开辟内存的一部分… 动态内存管理 1. 为什么存在动态内存管理2. 动态内存函数的介绍2.1 malloc函数和free函数2.2 calloc函数2.3 realloc函数 3. 常见的动态内存错误3.1 对NULL指针的解引用操作3.2 对动态开辟空间的越界访问3.3 对非动态开辟内存使用free函数3.4 使用free释放动态开辟内存的一部分3.5 对同一块动态内存多次释放3.6 动态开辟内存忘记释放(内存泄漏) 4. 几道经典的笔试题4.1 题目一4.2 题目二4.3 题目三4.4 题目四 5. C/C程序的内存开辟6. 柔性数组6.1 为什么需要柔性数组6.2 柔性数组的定义6.3 柔性数组的使用6.4 柔性数组的特点6.5 柔性数组的优势 1. 为什么存在动态内存管理 我们已经掌握的内存开辟方式有 int val 20;//在栈空间上开辟四个字节 char arr[10] {0};//在栈空间上开辟10个字节的连续空间 但上述开辟内存的方式有两个特点 空间开辟大小是固定的数组在声明时必须指定数组的长度他所需要的内存在编译时分配 但是对于空间的需求不仅仅是上述的情况。有时候我们需要的空间大小在程序运行的时候才能知道那数组的编译时开辟空间的方式就不能满足了。这时候就只能试试动态存开辟了。 2. 动态内存函数的介绍 2.1 malloc函数和free函数 C语言提供了一个动态内存开辟的函数 void* malloc (size_t size) 这个函数向内存申请一块连续可用的空间并返回指向这块空间的指针 如果开辟成功则返回一个指向开辟好空间的指针如果开辟失败则会返回NULL(空指针)因此malloc函数的返回值一定要做检查返回值的类型是void*所以malloc函数并不知道开辟空间的类型具体在使用时使用者自己决定如果size等于0这种行为C标准没有定义具体取决于编译器 C语言还提供了另一个函数free专门是用来做动态内存的释放和回收的 void free (void* ptr) 如果ptr指向的空间不是动态开辟的那么free的行为C语言并没有定义而是取决于编译器如果参数ptr是空指针(NULL)则该函数什么都不做 头文件: stdlib.h #include stdio.hint main() {//代码1int num 0;scanf(%d, num);int arr[num] {0};//代码2int* ptr NULL;ptr (int*)malloc(num*sizeof(int));if(NULL ! ptr)//判断ptr指针是否为空{int i 0;for(i0; inum; i){*(ptri) 0}}free(ptr);//释放ptr所指向的动态内存ptr NULL;//是否有必要return 0; }注意: malloc一定要和free搭配使用用完切记要释放内存ptrNULL是十分有必要的避免ptr成为野指针malloc函数只负责分配内存并不会将内存中的值初始化为0里面是一些随机值 2.2 calloc函数 C语言还提供了一个函数叫 calloc calloc 函数也用来动态内存分配。原型如下 void* calloc (size_t num, size_t size) 函数的功能是为num个大小为size的元素开辟一块空间并且把空间的每块区域初始化为0 #include stdio.h #include stdlib.h int main() {int *p (int*)calloc(10, sizeof(int));if(NULL ! p){//使用空间}free(p);p NULL;return 0; }2.3 realloc函数 realloc函数的出现让动态内存管理更加灵活有时会我们发现过去申请的空间太小了有时候我们又会觉得申请的空间过大了那为了合理的时候内存我们一定会对内存的大小做灵活的调整。那 realloc 函数就可以做到对动态开辟内存大小的调整 函数原型如下: void* realloc (void* ptr, size_t size) ptr是要调整的内存地址size 调整之后新大小返回值为调整之后的内存起始位置这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到新的空间realloc在调整内存空间的是存在两种情况 1.原来空间后面有足够大的空间 当是情况1 的时候要扩展内存就直接原有内存之后直接追加空间原来空间的数据不发生变化 2.原来的空间后面没有足够大的空间 当是情况2 的时候原有空间之后没有足够多的空间时扩展的方法是在堆空间上另找一个合适大小的连续空间来使用。这样函数返回的是一个新的内存地址。 由于上述两种情况,在使用realloc函数时就要注意 #include stdio.h int main() {int *ptr (int*)malloc(100);if(ptr ! NULL){//业务处理}else{exit(EXIT_FAILURE); }//扩展容量//代码1ptr (int*)realloc(ptr, 1000);//这样可以吗(如果申请失败会如何)//代码2int*p NULL;p realloc(ptr, 1000);if(p ! NULL){ptr p;}//业务处理free(ptr);return 0;}注意: 不能用之前的指针直接指向realloc函数扩展的新空间因为如果扩展失败返回空指针那么意味着之前的空间找不到了就导致内存泄漏正确的做法是新创建一个指针去接收如果该指针不为空再将地址赋给原来的指针 3. 常见的动态内存错误 3.1 对NULL指针的解引用操作 void test() {int *p (int *)malloc(INT_MAX/4);*p 20;//如果p的值是NULL就会有问题free(p); }解决这个问题的方法是申请完的空间在使用前一定要判断不为空在使用 3.2 对动态开辟空间的越界访问 void test() {int i 0;int *p (int *)malloc(10*sizeof(int));if(NULL p){exit(EXIT_FAILURE);}for(i0; i10; i){*(pi) i;//当i是10的时候越界访问}free(p); }解决这个问题的方法是在访问时自己心里看清楚有没有越界在执行程序 3.3 对非动态开辟内存使用free函数 void test() {int a 10;int *p a;free(p);//ok? }这种做法也是错误的free只能释放动态开辟的内存解决方法是释放的时候看清楚 3.4 使用free释放动态开辟内存的一部分 void test() {int *p (int *)malloc(100);p;free(p);//p不再指向动态内存的起始位置 }free函数只能释放一整个动态开辟的内存不能从中间某个位置开始释放 使用时要注意 3.5 对同一块动态内存多次释放 void test() {int *p (int *)malloc(100);free(p);free(p);//重复释放 }free只能释放一次动态开辟的内存不能多次释放使用时要注意哦 3.6 动态开辟内存忘记释放(内存泄漏) void test() {int *p (int *)malloc(100);if(NULL ! p){*p 20;} } int main() {test();while(1);}p指针是局部变量当调用完test函数时指针被销毁但申请的空间还在但没有之前的指针也就无法在访问这块地址这就导致内存一直被占用其他程序也无法使用这就是内存泄漏问题 切记: 申请的空间在使用完毕后一定要正确的释放 4. 几道经典的笔试题 4.1 题目一 void GetMemory(char *p) {p (char *)malloc(100); }void Test(void) {char *str NULL;GetMemory(str);strcpy(str, hello world);printf(str); }上面的程序test()函数执行会发生什么情况 GetMemory(str);将str的值传递给char*类型的指针p由于传的不是地址所以指针p和指针str指向的是不同的地址对于str来说地址里的值仍然是NULL对一个NULL去复制程序就会崩溃 4.2 题目二 char *GetMemory(void) {char p[] hello world;return p; }void Test(void) {char *str NULL;str GetMemory();printf(str); }请问执行Test()函数会发生什么 str GetMemory();这句话调用了GetMemory()函数并用char*指针接收该函数的返回值但char p[]数组是在该函数内部创建的虽然可以将数组p的地址返回给str但当str拿对应的地址去访问p之前的空间时这片空间已经被操作系统回收了所以就属于非法访问了打印出来是一些乱码 4.3 题目三 void GetMemory(char **p, int num) {*p (char *)malloc(num); } void Test(void) {char *str NULL;GetMemory(str, 100);strcpy(str, hello);printf(str); }这道题看上去没什么大问题但是有一个细节在使用完动态开辟的内存后没有及时释放free()导致内存泄漏 4.4 题目四 void Test(void) {char *str (char *) malloc(100);strcpy(str, hello);free(str);if(str ! NULL){strcpy(str, world);printf(str);} }这道题问题在于在free完之后没有及时将指针str即使置NULL所以导致下面的if语句被执行但str开辟的空间已经被释放掉所以也属于非法访问了但是由于我们进行的是字符串的拷贝,所以world还是会被拷贝到当前地址并成功输出但我们要知道这实际上是错误的 5. C/C程序的内存开辟 C/C程序内存分配的几个区域 栈区stack在执行函数时函数内局部变量的存储单元都可以在栈上创建函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中效率很高但是分配的内存容量有限。 栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、返回地址等。堆区heap一般由程序员分配释放 若程序员不释放程序结束时可能由OS(操作系统)回收 。分配方式类似于链表。数据段(静态区)(static)存放全局变量、静态数据。程序结束后由系统释放。代码段存放函数体(类成员函数和全局函数)的二进制代码。 6. 柔性数组 6.1 为什么需要柔性数组 我们平时在VS上只能指定长度固定的数组而不能灵活去改变数组的长度而且在定义一个数组时[ ]括号中必须是常量那么我们如果事先不知道要创建大小为多少的数组时应该怎么办?此时就需要C语言提供的另一种方式即柔性数组 6.2 柔性数组的定义 结构中的最后一个元素允许是未知大小的数组这就叫做『柔性数组』成员 typedef struct st_type {int i;int a[0];//柔性数组成员 }type_a;//有些编译器不支持上述写法可以按照下面来定义typedef struct st_type {int i;int a[];//柔性数组成员 }type_a;6.3 柔性数组的使用 #include stdlib.h struct Stu {int num;int grade[]; }; int main() {struct Stu* p (struct Stu*)malloc(sizeof(struct Stu) 20);if (p ! NULL){p-num 100;for (int i 0;i 5;i){p-grade[i] i1;printf(%d\n, p-grade[i]);}}free(p);p NULL; }在内存中num和grade在一个开辟的动态内存中 6.4 柔性数组的特点 结构中的柔性数组成员前面必须至少一个其他成员。sizeof 返回的这种结构大小不包括柔性数组的内存。包含柔性数组成员的结构用malloc ()函数进行内存的动态分配并且分配的内存应该大于结构的大小以适应柔性数组的预期大小。 6.5 柔性数组的优势 上述代码还可以设计为 #include stdlib.h struct Stu {int num;int* ptr; };int main() {struct Stu* p (struct Stu*)malloc(sizeof(struct Stu));if (p ! NULL){p-ptr (int*)malloc(sizeof(int)*5);if (p-ptr ! NULL){for (int i 0;i 5;i){p-ptr[i] i 1;printf(%d\n, p-ptr[i]);}}}free(p-ptr);p-ptr NULL;free(p);p NULL; }两者的区别在于在内存中的分布不同 情况一: 这种情况结构体变量是在栈中创建的柔性数组是在堆中创建的 情况二: 这种情况结构体和动态开辟的数组都是在堆上存储 第一种是通过柔性数组来实现第二种是通过普通的指针来实现我们来看看柔性数组的优势 第一个好处是方便内存释放 如果我们的代码是在一个给别人用的函数中你在里面做了二次内存分配并把整个结构体返回给用户。用户调用free可以释放结构体但是用户并不知道这个结构体内的成员也需要free所以你不能指望用户来发现这个事。所以如果我们把结构体的内存以及其成员要的内存一次性分配好了并返回给用户一个结构体指针用户做一次free就可以把所有的内存也给释放掉。 第二个好处是这样有利于访问速度. 连续的内存有益于提高访问速度也有益于减少内存碎片

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/913110.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于CompatibilityHID例程的使用

CompatibilityHID例程主要演示HID和串口之间的数据传输 1、首先注意工程要根据MCU不同型号进行相应的配置,具体可参考下链接: EVT-CH32x系列芯片EVT工程使用注意说明2、例程演示需要用到相应的工具,下载链接如下:H…

【CVCVCV】GAN代码解析

【CVCVCV】GAN代码解析Posted on 2025-09-23 16:06 SaTsuki26681534 阅读(0) 评论(0) 收藏 举报0 通过读GAN的代码了解一下常规深度学习模型的整体工程结构 1

实用指南:通过ssh远程linux 盒子

实用指南:通过ssh远程linux 盒子2025-09-23 16:07 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !impor…

海外推广是什么工作seo网站代码

main.m // 点语法-编译器特性,编译器遇到点语法会自动展开成相应的 //语法 //为了让其他语言的程序员能快速入手OC加入了点语法 //点语法的本质还是方法调用,不是访问成员变量 //(区别java,java的点语法是访问成员变量 //OC里面就…

SystemVerilog 代码风格指南

代码被阅读的频率远远超过编写的频率。在团队中保持一致的编码风格能够显著提升代码的可读性,这是节省工程时间最有效(也是最简单)的方法之一。在众多编程语言中,Python 可以说是最优雅的。阅读他人编写的 Python …

赋能智慧化工:无锡哲讯科技SAP解决方案,构筑安全、合规与高效的数字新底座

赋能智慧化工:无锡哲讯科技SAP解决方案,构筑安全、合规与高效的数字新底座在波澜壮阔的化工产业图景中,效率、安全与合规是永恒的生命线。随着全球市场竞争加剧、环保法规日趋严格以及供应链不确定性增加,数字化转…

seo的网站网站建立计划书

JDK和JRE的区别 定义:JDK(Java Development Kit)是Java开发工具包的缩写,它是Java开发人员必备的工具。JDK包含了编译器(javac)、Java虚拟机(JVM)和Java类库等开发工具和资源。它提供了开发、编译、调试和运行Java程序所需的一切…

拼多多网站建设框架图英文seo

在ThinkPHP 5中实现带有搜索条件、名称、时间和手机号的3个联表查询(UNION ALL),您可以按照以下步骤进行操作: 确保已经配置好数据库连接信息和相关的模型。 使用union()方法来构建3个联表查询,同时在每个查询中添加所…

wordpress建一个网站用react做的网站

本文通过原理和示例对相机设置参数“黑电平”进行讲解,以帮助大家理解和使用。 原理 相机中黑电平原理是将电平增大,可以显示更多暗区细节,可能会损失一些亮区,但图像更多的关注暗区,获取完图像信息再减掉。只是为了…

网站颜色搭配表建设一个旅游平台网站需要多少资金

目录 一、字体 二、背景图片 三、显示方式 四、类型转换 五、相对定位 六、绝对定位 七、固定定位 八、Index 九、粘性定位 十、内边距 十一、外边距 十二、边框 十三、盒子尺寸计算问题 十四、清楚默认样式 十五、内容溢出 十六、外边距的尺寸与坍塌 十七、行…

大数据 做网站流量统计开一家网络公司做网站前景如何

本文是对rust嵌入式开发的补充,就当时遗留的一些问题进行增补与修正。 RTIC中的任务处理 在上篇文章中还不是很理解rtic的工作机制。但写东东进行总结的好处就体现出来了,在上篇文章中提到了rtic的app入口本就是一个进程宏,所以在写完文章后…

怎么给自己公司做网站在线直播网站开发实战项目

在一个化装舞会上拍下的一位和蔼热情的瑞士母亲。菲律宾女孩好象是典型的法国帅哥。穿着印度肚皮舞服装的美国女孩。穿着蒙古袍的法国帅哥和美丽的像白雪公主一样的瑞士姑娘。蒙古袍穿在他们身上还挺合适。

建筑行业招聘网站排行榜用什么做响应式网站

1、查看串口的驱动信息 2、驱动安装文件:http://www.wch.cn/download/CH341SER_EXE.html 3、参考驱动资料:https://blog.csdn.net/jazzsoldier/article/details/70169732 转载于:https://www.cnblogs.com/qy1234/p/10146303.html

lmhosts和hosts的时效

lmhosts和hosts的时效两者都可以绑定机器名和ip,并且绑定后立刻生效。 但对于取消绑定后,hosts是立刻生效的;而lmhosts则需要重启才生效。 假如两个文件同时绑定同样的名称但ip不一样,则以hosts的为准 另lmhosts.s…

会用框架做网站能找到工作吗苏州网页制作

背景: 目前用iperf3打流传输速率达不到要求,千兆实际要求跑到800M以上: 优化方案: 1.优化defconfig: 首先编译user版本验证看是否正常 debug版本关闭CONFIG_SLUB_DEBUG_ON宏控。 2.找FAE ,通过更换驱动,或者更新驱动来优化 3.绑定大核: 以8125网卡为例,udp…

Https模式访问wcf方法配置

Https模式访问wcf方法配置<?xml version="1.0" encoding="utf-8"?> <configuration> <appSettings><add key="aspnet:UseTaskFriendlySynchronizationContext&quo…

芯之所向,智造未来:无锡哲讯科技赋能芯片行业的高效管理与数字革新

芯之所向,智造未来:无锡哲讯科技赋能芯片行业的高效管理与数字革新在当今这个由数字技术驱动的时代,芯片已成为名副其实的“工业粮食”,其战略重要性不言而喻。然而,芯片产业本身也面临着前所未有的挑战:工艺流程…

云南省新农村建设网站东营网站建设怎么建设

*本文原创作者&#xff1a;MyselfExplorer&#xff1b;翻译编辑&#xff1a;楼兰&#xff0c;本文属FreeBuf原创奖励计划&#xff0c;未经许可禁止转载 我想给你一把打开这扇门的钥匙&#xff0c;而你要做的便是静静的聆听接下来的故事。挖掘 0day 一般需要掌握fuzzing&#xf…

书荒小说阅读器是哪个网站做的学生登录注册入口

第十一章 分布式搜索引擎 elasticsearch 七、搜索结果处理 搜索的结果可以按照用户指定的方式去处理或展示。 1. 排序 elasticsearch 默认是根据相关度算分&#xff08;_score&#xff09;来排序&#xff0c;但是也支持自定义方式对搜索结果排序。可以排序字段类型有&#…

网站搭建报价企业的网站建设费账务处理

产品的实现需要做好产品规划&#xff0c;而产品的规划决定了产品的方向。本文从战略规划的重要性、产品定位、设计产品架构图三个方向&#xff0c;详细地为大家梳理了产品实现的前期准备。 我们知晓了如何去发掘问题&#xff0c;并找到解决方案。 可对于问题的处理&#xff0c…