当前位置: 首页 > 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;共同探讨和分享关于…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

Caliper 配置文件解析:fisco-bcos.json

config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...

关于uniapp展示PDF的解决方案

在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项&#xff1a; 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库&#xff1a; npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分&#xff1a;派生类构造函数与析构函数 当创建一个派生类对象时&#xff0c;基类成员是如何初始化的&#xff1f; 1.当派生类对象创建的时候&#xff0c;基类成员的初始化顺序 …...

ubuntu系统文件误删(/lib/x86_64-linux-gnu/libc.so.6)修复方案 [成功解决]

报错信息&#xff1a;libc.so.6: cannot open shared object file: No such file or directory&#xff1a; #ls, ln, sudo...命令都不能用 error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory重启后报错信息&…...