当前位置: 首页 > news >正文

C语言第三十四弹---动态内存管理(下)

个人主页: 熬夜学编程的小林

💗系列专栏: 【C语言详解】 【数据结构详解】

动态内存管理

1、动态内存经典笔试题分析

1.1、题目1

1.2、题目2

1.3、题目3

1.4、题目4

2、柔性数组

2.1、柔性数组的特点

2.2、柔性数组的使用

2.3、柔性数组的优势

3、总结C/C++中程序内存区域划分

总结


1、动态内存经典笔试题分析

1.1、题目1

void GetMemory(char *p){p = (char *)malloc(100);}
void Test(void){char *str = NULL;GetMemory(str);strcpy(str, "hello world");printf(str);}int main(){Test();return 0;}
请问运行Test 函数会有什么样的结果?
根据C语言顺序结构原则,进入Test()函数之后逐条执行,先创建一个指针变量str指向NULL,再执行GetMemory函数,将 str 传入函数,然后动态开辟100字节空间,但是指针变量 p 出了函数会自动销毁,然后执行strcpy函数,但是此处str 指向NULL, 程序对NULL进行解引用操作,程序崩溃 ,前面函数动态开辟内存没有手动释放,因此 会导致内存泄漏

1.2、题目2

char *GetMemory(void){char p[] = "hello world";return p;}
void Test(void){char *str = NULL;str = GetMemory();printf(str);}int main(){Test();return 0;}
请问运行Test 函数会有什么样的结果?
根据C语言顺序结构原则,进入Test()函数之后逐条执行,先创建一个指针变量str指向NULL,再执行GetMemory函数,将数组首元素地址作为返回值返回给str,但是此处是在栈区开辟的空间,函数结束后就会销毁,此时str就为野指针, 打印野指针(非法访问内存)就会出现肉眼看不懂的文字。

1.3、题目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);}int main(){Test();return 0;}
请问运行Test 函数会有什么样的结果?
根据C语言顺序结构原则,进入Test()函数之后逐条执行,先创建一个指针变量str指向NULL,再执行GetMemory函数,将str的地址传入函数,将*p开辟100个内存空间,即给str开辟100个内存空间,然后执行strcpy函数,将hello\0拷贝到str,再将str打印出来,此处没有太大问题,唯一的问题是 str指向的空间是动态开辟的,没有手动释放,会导致内存泄漏。

1.4、题目4

void Test(void){char *str = (char *) malloc(100);strcpy(str, "hello");free(str);if(str != NULL){strcpy(str, "world");printf(str);}}
int main()
{Test();return 0;
}
请问运行Test 函数会有什么样的结果?
根据C语言顺序结构原则,进入Test()函数之后逐条执行,先创建一个指针变量str指向动态开辟100字节的空间,然后将该空间拷贝hello\0,然后释放该空间(只是不能正常使用,实际还是指向该位置),此时str还是指向动态开辟的空间,因此指向strcpy函数,将world\0拷贝到str,然后打印str,即 打印出world,只是str为野指针,即非法访问内存。

2、柔性数组

也许你从来没有听说过柔性数组(flexible array)这个概念,但是它确实是存在的。
C99 中, 结构中 最后⼀个元素 允许是 未知大小的数组 ,这就叫做『柔性数组』成员
例如:
typedef struct st_type
{int i;int a[0];//柔性数组成员
}type_a;
有些编译器会报错无法编译可以改成:
typedef struct st_type
{int i;int a[];//柔性数组成员
}type_a;

2.1、柔性数组的特点

结构中的柔性数组成员前面必须至少⼀个其他成员。
sizeof 返回的这种结构大小不包括柔性数组的内存。
包含柔性数组成员的结构用malloc ()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。
例如:
typedef struct st_type
{int i;int a[0];//柔性数组成员
}type_a;
int main()
{printf("%d\n", sizeof(type_a));//输出的是4return 0;
}

2.2、柔性数组的使用

//代码1
#include <stdio.h>
#include <stdlib.h>
typedef struct st_type
{int i;int a[0];//柔性数组成员
}type_a;
int main()
{int i = 0;type_a *p = (type_a*)malloc(sizeof(type_a)+100*sizeof(int));//业务处理p->i = 100;for(i=0; i<100; i++){p->a[i] = i;}free(p);return 0;
}
这样柔性数组成员a,相当于获得了100个整型元素的连续空间。

2.3、柔性数组的优势

上述的 type_a 结构也可以设计为下面的结构,也能完成同样的效果
//代码2
#include <stdio.h>
#include <stdlib.h>
typedef struct st_type
{int i;int *p_a;
}type_a;
int main()
{type_a *p = (type_a *)malloc(sizeof(type_a));p->i = 100;p->p_a = (int *)malloc(p->i*sizeof(int));//业务处理for(i=0; i<100; i++){p->p_a[i] = i;}//释放空间free(p->p_a);p->p_a = NULL;free(p);p = NULL;return 0;
}
上述 代码 1 和 代码 2 可以完成同样的功能,但是 方法 1 的实现有两个好处:
第⼀个好处是:方便内存释放
如果我们的代码是在⼀个给别人用的函数中,你在里面做了⼆次内存分配,并把整个结构体返回给用户。用户调用free可以释放结构体,但是用户并不知道这个结构体内的成员也需要free,所以你不能指望用户来发现这个事。所以,如果我们把结构体的内存以及其成员要的内存⼀次性分配好了,并返回给用户⼀个结构体指针,用户做⼀次free就可以把所有的内存也给释放掉。
第⼆个好处是:这样有利于访问速度.
连续的内存有益于提高访问速度,也有益于减少内存碎片。(其实,我个⼈觉得也没多高了,反正你跑不了要用做偏移量的加法来寻址)
扩展阅读:
C语⾔结构体里的数组和指针icon-default.png?t=N7T8https://coolshell.cn/articles/11377.html

3、总结C/C++中程序内存区域划分

C/C++程序内存分配的几个区域:
1. 栈区(stack):在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、返回地址等。
2. 堆区(heap):⼀般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。分配方式类似于链表。
3. 数据段(静态区):(static)存放全局变量、静态数据。程序结束后由系统释放。
4. 代码段:存放函数体(类成员函数和全局函数)的⼆进制代码。

总结


本篇博客就结束啦,谢谢大家的观看,如果公主少年们有好的建议可以留言喔,谢谢大家啦!

相关文章:

C语言第三十四弹---动态内存管理(下)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 动态内存管理 1、动态内存经典笔试题分析 1.1、题目1 1.2、题目2 1.3、题目3 1.4、题目4 2、柔性数组 2.1、柔性数组的特点 2.2、柔性数组的使用 2.3、…...

PDN分析及应用系列二-简单5V电源分配-Altium Designer仿真分析-AD

PDN分析及应用系列二 —— 案例1:简单5V电源分配 预模拟DC网络识别 当最初为PCB设计打开PDN分析仪时,它将尝试根据公共电源网络命名法从设计中识别所有直流电源网络。 正确的DC网络识别对于获得最准确的模拟结果非常重要。 在示例项目中已经识别出主DC网络以简化该过程。 …...

Vue开发实例(一)Vue环境搭建第一个项目

Vue环境搭建&第一个项目 一、环境搭建二、安装Vue脚手架三、创建Vue项目 一、环境搭建 下载方式从官网下载&#xff1a;http://nodejs.cn/download/ 建议下载v12.16.0版本以上的&#xff0c;因为版本低无法创建Vue的脚手架 检验是否安装成功 配置环境变量 新增NODE_HOME&…...

将SpringBoot项目改造成solon项目

solon项目介绍 官网 Java “生态型”应用开发框架&#xff1a;更快、更小、更简单。 启动快 5 &#xff5e; 10 倍&#xff1b;并发高 2&#xff5e; 3 倍&#xff1b; 内存省 1/3 ~ 1/2&#xff1b;打包缩到 1/2 ~ 1/10&#xff1b;同时支持 java8, java11, java17, java21&a…...

更详细的软件测试理论基础:流程,开发、测试模型,测试分类,测试用例及其设计方法,缺陷

文章目录 一、测试流程二、开发模型1、 瀑布模型2、增量模型3、快速模型4、其他 三、测试模型1、V模型2、W模型 四、测试分类五、测试用例 test case六、测试用例设计方法1、等价类划分法2、边界值分析法3、因果图法4、判定表法5、正交法6、场景法7、流程分析法8、错误推测法方…...

input css padding

这样控件会跑出外套控件在HTML JSP里面是经常出现的。但有些外国adobe的as控件不存在这种情况&#xff0c;这是因为内层控件定义的时候不能超出外层控件的范围。 修改下&#xff1a;去掉原来css padding&#xff0c;然后加上宽度和高度...

如何打印 springboot 框架中 接收请求的日志

在 Spring Boot 框架中&#xff0c;您可以使用日志来记录接收请求和发送响应的详细信息。Spring Boot 默认使用 SLF4J&#xff08;Simple Logging Facade for Java&#xff09;作为日志抽象层&#xff0c;并支持多种日志实现&#xff0c;如 Logback、Log4j2 等。以下是一种常见…...

JVM的内存区域划分

JVM即Java虚拟机&#xff0c;是Java实现跨平台交互能力的核心&#xff0c;Java编译后的.class文件&#xff0c;就是通过虚拟机和操作系统进行交互的&#xff1b; 常见的虚拟机有&#xff1a;JVM、VMwave、Virtual Box&#xff0c;目前最主流使用的JVM是HotSpot VM&#xff1b;…...

YOLOv9有效改进|使用动态蛇形卷积Dynamic Snake Convolution

专栏介绍&#xff1a;YOLOv9改进系列 | 包含深度学习最新创新&#xff0c;主力高效涨点&#xff01;&#xff01;&#xff01; 一、改进点介绍 使用ICCV2023中的动态蛇形卷积替换YOLOv9网络中的Conv模块。 二、Dynamic Snake Convolution模块详解 2.1 模块简介 应用场景&#x…...

设计模式学习笔记 - 设计原则 - 1.单一职责原则

前言 前面我们提到过 SOLID 原则&#xff0c;实际上 SOLID 由 5 个设计原则组成&#xff0c;分别是&#xff1a;单一职责原则、开闭原则、里氏替换原则、接口隔离原则和依赖反转原则。它们分别对应 SLOID 中的 S、O、L、I、D 这 5 个英文字母。 今天来学习下 SOLID 原则中的第…...

飞天使-学以致用-devops知识点4-SpringBoot项目CICD实现(实验失败,了解大概流程)

文章目录 代码准备创建jenkins 任务测试推送使用项目里面的jenkinsfile 进行升级操作 文字版本流程项目构建 代码准备 推送代码到gitlab 代码去叩叮狼教育找 k8s 创建jenkins 任务 创建一个k8s-cicd-demo 流水线任务 将jenkins 里面构建时候的地址还有token&#xff0c; 给到…...

使用HTML5画布(Canvas)模拟图层(Layers)效果

使用HTML5画布&#xff08;Canvas&#xff09;模拟图层&#xff08;Layers&#xff09;效果 在图形处理和计算机图形学中&#xff0c;图层&#xff08;Layers&#xff09;是指将图像分成不同的可独立编辑、组合和控制的部分的技术或概念。每个图层都可以包含不同的图形元素、效…...

违背祖训,微软骚操作强制用户更新至 Win 11 23H2

话说&#xff0c;大伙儿有让 Windows 操作系统一直保持最新版习惯吗&#xff1f; 根据以往惯例&#xff0c;Windows 系统更新是个比较玄学的存在&#xff0c;谁也不能保证随手更新后会不会出现什么奇葩 Bug。 因此对于不少同学来说&#xff0c;Windows 更新到一个稳定版本后&a…...

MISRA C++ 2023指南:您需要了解的一切

MISRA C 2023可以帮助使用现代C语言的组织开发安全关键型软件。使用新的MISRA标准&#xff0c;开发人员可以通过确保和记录其软件应用程序的MISRA合规性&#xff0c;满足IEC 6108或ISO 26262等功能安全标准给出的静态分析要求。 什么是MISRA C2023? 以便使用C17进行安全可靠…...

Vue:【亲测可用】父组件数组包对象,传给子组件对象,子组件修改属性(字段)后,父组件没有更新

场景&#xff1a;vue中父组件数组包对象&#xff0c;传给子组件对象&#xff0c;子组件修改属性&#xff08;字段&#xff09;后&#xff0c;父组件没有更新 代码&#xff1a; # 父组件 <div v-for"(object, name, index) in arr" :key"index"><…...

hbase学习十:客户端实现与Meta表解析

1、客户端实现 hbase社区的客户端一般是java客户端。 HBase也支持Shell交互式客户端。Shell客户端实质是用JRuby(用Java编写的Ruby解释器,方便Ruby脚本跑在JVM虚拟机上)脚本调用官方HBase客户端来实现的。因此,各种客户端的核心实现都在社区Java版本客户端上。 客户端访…...

《OpenScene: 3D Scene Understanding with Open Vocabularies》阅读笔记1

传统的3D场景理解方法依赖于带标签的3D数据集,用于训练一个模型以进行单一任务的监督学习。我们提出了OpenScene,一种替代方法,其中模型在CLIP特征空间中预测与文本和图像像素共同嵌入的3D场景点的密集特征。这种零样本方法实现了与任务无关的训练和开放词汇查询。例如,为了…...

数据结构 - Trie树(字符串统计、最大异或对)

文章目录 前言Part 1&#xff1a;Trie字符串统计1.题目描述输入格式输出格式数据范围输入样例输出样例 2.算法 Part 2&#xff1a;最大异或对1.题目描述输入格式输出格式数据范围输入样例输出样例 2.算法 前言 本篇博客将介绍Trie树的常见应用&#xff0c;包括&#xff1a;Trie…...

2. vue 工程创建

1. 基于 vite创建 官方文档: https://v3.cn.vuejs.org/guide/installation.html#vite vite官网: https://vitejs.cn 使用vite创建的优势&#xff1a; 开发环境中&#xff0c;无需打包操作&#xff0c;可快速的冷启动。轻量快速的热重载(HMR)。真正的按需编译&#xff0c;不再…...

2024绿色能源、城市规划与环境国际会议(ICGESCE 2024)

2024绿色能源、城市规划与环境国际会议(ICGESCE 2024) 一、【会议简介】 随着全球气候变化和环境问题日益严重&#xff0c;绿色能源和可持续发展已成为全球关注的焦点。本次会议旨在汇聚全球在绿色能源、城市规划与环境领域的专家、学者和实践者&#xff0c;共同探讨和分享关于…...

html怎么转rollup plugin html_Rollup如何通过插件处理HTML入口

rollup-plugin-html 未生效的根本原因是 Rollup 默认不处理 HTML&#xff0c;需将 html() 插件置于 resolve() 和 commonjs() 之前&#xff0c;并配置 transformers、路径映射及环境变量注入方式。rollup-plugin-html 为什么没生效&#xff1f;常见现象是 HTML 文件被当成普通资…...

智能营销新纪元:揭秘星图销冠系统如何用AI自动化重塑企业获客生态

在数字化转型浪潮席卷各行各业的今天&#xff0c;企业获客成本持续攀升&#xff0c;传统营销方式疲态尽显。寻找一家真正专业AI企业、服务好AI服务商&#xff0c;引入一套能打通公域引流与私域转化全链路的智能系统&#xff0c;已成为众多市场决策者的核心诉求。市场上声称能提…...

免疫治疗新视角:CD47 (分化簇47) 信号通路机制与药物研发技术综述

在生物制药与免疫学领域&#xff0c;CD47 (分化簇47) 作为连接先天免疫与适应性免疫的关键节点&#xff0c;近年来备受关注。作为一种广泛表达的跨膜糖蛋白&#xff0c;它通过复杂的信号轴调控免疫细胞的吞噬行为。本文将深入剖析CD47的作用机制、当前药物研发的临床进展以及未…...

别再数据线了!用FastAPI 分钟搭个局域网文件+剪贴板神器俚

为 HagiCode 添加 GitHub Pages 自动部署支持 本项目早期代号为 PCode&#xff0c;现已正式更名为 HagiCode。本文记录了如何为项目引入自动化静态站点部署能力&#xff0c;让内容发布像喝水一样简单。 背景/引言 在 HagiCode 的开发过程中&#xff0c;我们遇到了一个很现实的问…...

【2026年阿里巴巴集团暑期实习- 4月8日-开发岗-第三题- 困难不平衡数】(题目+思路+JavaC++Python解析+在线测试)

题目内容 我们定义一个整数:倘若数字位中奇数数字的个数不等于偶数数字的个数,那么我们称这个整数是一个不平衡数。 现在给定一个由数字 000 到 999 组成的字符串,求解其中有多少子序列满足:这些子序列所代表的数是一个不平衡数,且不包含前导零。 由于答案可能很大,请…...

需求动态感知与策略协同优化的机器学习模型研究——以企业供应链需求优化为例

需求动态感知与策略协同优化的机器学习模型研究——以企业供应链需求优化为例 摘要 在日益复杂和动态的市场环境中,企业供应链面临着需求波动加剧、决策链条冗长、多维目标冲突等严峻挑战。传统基于历史统计模型和静态策略的优化方法难以实时感知需求变化并协同调整供应链决…...

QY-02-YS 雨量水位监测站 雨水情测报助手

雨量监测站配置1&#xff09;不锈钢支架&#xff0c;高度为1.2米2&#xff09;雨量传感器、水位传感器3&#xff09;太阳能供电&#xff1a;太阳能电池板&#xff0c;蓄电池4&#xff09;数据采集发送器数据传输采用4G和短信息兼容方式&#xff1b;具备向三个&#xff08;或以上…...

从零构建ROS履带车:揭秘AI与无人驾驶核心技术(2)

1. 从零搭建ROS履带车的硬件基础 想要打造一台能跑能跳的智能履带车&#xff0c;第一步得把硬件架子搭结实。我当年第一次做履带车时&#xff0c;用的就是淘宝上200块钱的金属履带底盘套件&#xff0c;搭配Jetson Nano开发板作为大脑。这里有个实用建议&#xff1a;选择履带宽度…...

ArcGIS空间连接实战:如何高效挂接地图斑属性到mdb数据库

ArcGIS空间连接实战&#xff1a;高效挂接地图斑属性到mdb数据库的完整指南 在空间数据处理工作中&#xff0c;将属性数据与空间图形精准关联是GIS分析的基础环节。许多技术人员在使用ArcGIS进行地图斑属性挂接时&#xff0c;常遇到数据不匹配、连接失败或效率低下的问题。本文将…...

HagiCode Desktop 混合分发架构解析:如何用 PP 加速大文件下载肛

一、Actor 模型&#xff1a;不是并发技巧&#xff0c;而是领域单元 Actor 模型的本质是&#xff1a; Actor 是独立运行的实体 Actor 之间只通过消息交互 Actor 内部状态不可被外部直接访问 Actor 自行决定如何处理收到的消息 Actor 模型真正解决的是&#xff1a; 如何在不共享状…...