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

【C语言__动态内存管理__复习篇6】

目录

前言

一、动态内存管理

二、动态内存函数

        2.1 malloc 

        2.2 free

        2.3 calloc

        2.4 realloc

三、动态内存常见的6个使用错误

        3.1 接收malloc/calloc返回的参数后未及时检查是否为NULL

        3.2 越界访问动态内存空间

        3.3 对非动态开辟的内存使用free释放

        3.4 使用free只释放了动态开辟内存的一部分

        3.5 对同一块动态内存多次释放

        3.6 动态开辟内存忘记释放造成内存泄露

四、动态内存经典笔试题

        4.1 题目1

        4.2 题目2

        4.3 题目3

        4.4 题目4

五、柔性数组

六、C/C++中程序内存区域划分


前言

本篇主要讨论以下问题:

动态内存基础知识点:

1. 为什么会出现动态内存的概念

2. 与动态内存有关的4个函数它们分别的作用、函数的参数、返回类型以及要注意的地方是什么

3. 知道动态开辟的内存是在堆区开辟空间的,如果不主动使用free释放开辟的动态内存空间,那么只能等程序结束后由操作系统释放了。(不可取,一定要记得自己用free去释放)

动态内存避坑指南:

4. 动态内存开辟和使用过程中常见的有哪6大错误

5. 动态内存经典笔试题,找出代码中错误的点

柔性数组:

6. 怎样的数组才能被称为柔性数组,含柔性数组的结构体是如何开辟内存空间的,又是如何找到结构体变量的成员变量的

了解内存有哪几个重要的区域:

7.内存有哪几个重要的区域

 一、动态内存管理

1. 在没有学习动态内存管理前 ,我们知道的为变量开辟内存的方式有两种:① 一次申请一个变量的空间 ② 一次申请一块连续的空间,但这两种申请内存空间的方式有一个明显的缺点,就是申请的空间大小一旦确定就无法更改了,于是C语言中引入了动态内存的概念,我们可以利用4个与动态内存有关的函数,实现动态开辟内存空间。

二、动态内存函数

1. 4个与动态内存有关的函数所需的头文件都是<stdlib.h>

2.1 malloc 

1. malloc函数的作用:开辟size字节的动态内存空间。

2. 语法形式:void* malloc (size_t size)

    size_t size:表示向堆区一次性申请几个字节的空间。

    void*:返回类型之所以是void*(void*可接收任意类型的地址)是因为malloc只知道向内存的堆区申请几个字节的空间,并不知道将会存放什么类型的数据,但是程序员是知道的,所以在用malloc开辟动态内存后,一般会立即强制类型转换,直接用其他类型的指针变量接收

3. 如果malloc开辟内存成功,则返回一个指向开辟好空间的指针。

    如果malloc开辟内存失败,则返回一个NULL指针,因此在用指针接收malloc返回的地址后,需要检查指针内的地址是否为NULL

4. 如果malloc函数的参数size为0,这是标准未定义的,完全取决于编译器如何处理。

#include <stdio.h>
#include <stdlib.h>
int main()
{//开辟动态内存int* ps = (int*)malloc(10 * sizeof(int));//强制转换后再接收if (ps == NULL)//判断是否开辟失败{perror("malloc");return 1;//异常返回,返回非0}return 0;
}

2.2 free

1. free函数的作用:用于回收malloc/calloc/realloc开辟的动态内存空间

2. 语法形式:void free (void* ptr)

    void* ptr:表示指向malloc/calloc/realloc开辟的动态内存空间的指针。

3. free函数只是回收了ptr所指向的动态内存空间,但此时ptr中仍然存放着指向刚刚已被回收的动态内存空间的地址,因此在使用free函数后,应立即在后面一行中写上将ptr置NULL的操作,防止ptr野指针被使用。

4. 如果free函数的参数 ptr 指向的空间不是动态开辟的内存空间,这是标准未定义的,完全取决于编译器如何处理。

    如果free函数的参数是NULL,则free函数将什么都不会做。

#include <stdio.h>
#include <stdlib.h>
int main()
{//开辟动态内存int* ps = (int*)malloc(10 * sizeof(int));//强制转换后再接收if (ps == NULL)//判断是否开辟失败{perror("malloc");return 1;//异常返回,返回非0}//使用动态内存//释放动态内存free(ps);ps = NULL;return 0;
}

2.3 calloc

1. calloc函数的作用:为num个大小为size字节的元素开辟一块动态内存空间, 与malloc不同的是calloc会对开辟的空间每个字节都初始化为0

2. 语法形式:void* calloc (size_t num, size_t size)

    size_t mun:表示要分配的元素个数。

    size_t size:表示每个元素的大小。

    void*:和malloc函数的原因一致,在用calloc开辟动态内存后,一般会立即强制类型转换,直接用其他类型的指针变量接收

3. 如果calloc开辟内存成功,则返回一个指向开辟好空间的指针。

    如果calloc开辟内存失败,则返回一个NULL指针,因此在用指针接收malloc返回的地址后,需要检查指针内的地址是否为NULL

#include <stdio.h>
#include <stdlib.h>
int main()
{//开辟动态内存int* ps = (int*)calloc(10, sizeof(int));//强制转换后再接收if (ps == NULL)//判断是否开辟失败{perror("calloc");return 1;//异常返回,返回非0}//使用动态内存,看看calloc默认初始化的值for (int i = 0; i < 10; i++){printf("%d ", *(ps + i));//屏幕上打印出了10个0}//释放动态内存free(ps);ps = NULL;return 0;
}

2.4 realloc

1. realloc函数的作用:调整用malloc/calloc/realloc开辟过的动态内存空间大小

2. 语法形式:void* realloc (void* ptr, size_t size)

    void* ptr:表示指向malloc/calloc/realloc开辟的动态内存空间的指针。

    size_t size:表示想要重新调整到的动态内存空间的大小。

    void*:和malloc函数的原因一致,在用calloc开辟动态内存后,一般会立即强制类型转换,直接用其他类型的指针变量接收

3. 如果realloc调整内存大小成功,则返回非NULL指针。

    如果realloc调整内存大小失败,则返回一个NULL指针,此时如果直接用ptr接收realloc返回的地址,会使得ptr连原本的动态内存空间都无法找到,也无法将原本的动态内存空间释放,所以在用realloc调整动态内存空间后,不会直接用ptr接收,而是会建立一个临时指针去接收,临时的指针接收后,判断如果临时指针不为NULL,则把临时指针内的地址赋值给ptr,并把临时的指针赋值为NULL;如果为NULL,则进行报错

4. 关于realloc函数返回的地址是什么的问题:

    情况一:原有空间之后有⾜够⼤的空间可以扩充,此时要扩展内存就直接会在原有内存之后直接追加空间,原来空间的数据不发⽣变化,realloc返回的地址值与ptr内的值一致。

    情况二:原有空间之后没有⾜够⼤的空间可以扩充,扩展的⽅法是,在堆空间上另找⼀个合适⼤⼩的连续空间来使⽤,同时把旧数据拷贝到新的空间,并释放旧的空间,这样函数返回的是⼀个新的内存地址。

5. realloc函数的隐藏技能:如果realloc函数的参数void* ptr部分传参为NULL,效果等同于malloc函数。

#include <stdio.h>
#include <stdlib.h>
int main()
{//开辟动态空间int* ps = (int*)malloc(10 * sizeof(int));if (ps == NULL){perror("malloc");return 1;}//调整动态空间int* ps2 = (int*)realloc(ps, 20 * sizeof(int));if (ps2 != NULL){ps = ps2;ps2 = NULL;}else{perror("realloc");return 1;}//释放动态内存free(ps);ps = NULL;return 0;
}

三、动态内存常见的6个使用错误

3.1 接收malloc/calloc返回的参数后未及时检查是否为NULL

#include <stdio.h>
#include <stdlib.h>
int main()
{int* p = (int*)malloc(10 * sizeof(int));*p = 20;//errreturn 0;
}

3.2 越界访问动态内存空间

#include <stdio.h>
#include <stdlib.h>
int main()
{//开辟动态内存空间int* p = (int*)malloc(10 * sizeof(int));if (p == NULL){perror("malloc");return 1;}//使用for (int i = 0; i < 12; i++){*(p + i) = i;//err}//释放动态内存空间free(p);p = NULL;return 0;
}

3.3 对非动态开辟的内存使用free释放

#include <stdio.h>
#include <stdlib.h>
int main()
{int a = 10;int* pa = &a;free(pa);//errpa = NULL;return 0;
}

3.4 使用free只释放了动态开辟内存的一部分

#include <stdio.h>
#include <stdlib.h>
int main()
{//开辟动态内存空间int* p = (int*)malloc(10 * sizeof(int));if (p == NULL){perror("malloc");return 1;}//使用动态空间for (int i = 0; i < 5; i++){*p = i;p++;}//释放动态内存空间free(p);//errp = NULL;return 0;
}

3.5 对同一块动态内存多次释放

#include <stdio.h>
#include <stdlib.h>
int main()
{//开辟动态内存空间int* p = (int*)malloc(10 * sizeof(int));if (p == NULL){perror("malloc");return 1;}//使用动态空间free(p);p = NULL;//释放动态内存空间free(p);//errp = NULL;return 0;
}

3.6 动态开辟内存忘记释放造成内存泄露

#include <stdio.h>
#include <stdlib.h>void Test()
{int* p = (int*)malloc(100);if (p == NULL){perror("malloc");return 1;}else{*p = 20;}//err,未释放动态内存
}int main()
{test();return 0;
}

四、动态内存经典笔试题

4.1 题目1

题目分析:代码的目的是想让字符串拷贝到动态开辟的内存中。

错误分析:① 采用了传值调用,改变形参,实参不受影响。

                  ② NULL不能被使用。

                  ③ 没有free动态内存。

#include <stdio.h>
#include <stdlib.h>void GetMemory(char* p)
{p = (char*)malloc(100);
}void Test(void)
{char* str = NULL;GetMemory(str);//传值调用strcpy(str, "hello world");//str==NULL,errprintf(str);
}int main()
{Test();return 0;
}
//修改代码
#include <stdio.h>
#include <stdlib.h>void GetMemory(char** p)
{*p = (char*)malloc(100);if (*p == NULL)//{perror("malloc");}
}void Test(void)
{char* str = NULL;GetMemory(&str);//strcpy(str, "hello world");printf(str);free(str);//str = NULL;//
}int main()
{Test();return 0;
}

4.2 题目2

错误分析:① 自定义函数返回了局部变量的地址

#include <stdio.h>
#include <stdlib.h>char* GetMemory(void)
{char p[] = "hello world";//err//static char p[] = "hello world";//修改代码:将上一行替换return p;
}void Test(void)
{char* str = NULL;str = GetMemory();printf(str);
}int main()
{Test();return 0;
}

4.3 题目3

错误分析:① 没有判断malloc是否返回的NULL

                  ② 没有用free释放动态内存空间

#include <stdio.h>
#include <stdlib.h>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;
}
//修改代码
#include <stdio.h>
#include <stdlib.h>void GetMemory(char** p, int num)
{*p = (char*)malloc(num);if (*p == NULL)//{perror("malloc");}
}void Test(void)
{char* str = NULL;GetMemory(&str, 100);strcpy(str, "hello");printf(str);//free(str);//str = NULL;
}int main()
{Test();return 0;
}

4.4 题目4

错误分析:① 没有判断malloc是否返回的NULL

                  ② free后没有及时将str置NULL

#include <stdio.h>
#include <stdlib.h>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;
}
//修改代码
#include <stdio.h>
#include <stdlib.h>void Test(void)
{char* str = (char*)malloc(100);if (str == NULL){perror("malloc");return 1;}strcpy(str, "hello");free(str);str = NULL;//无意义代码if (str != NULL){strcpy(str, "world");printf("str");}
}int main()
{Test();return 0;
}

五、柔性数组

1. C99中,结构体至少2个成员变量,若最后一个成员变量是一个未知大小的数组,则这个数组叫做柔性数组。( 未知大小的数组写法:① int arr[]; ② int arr[0];

2. 柔性数组的特点:

① 结构体中柔性数组成员前必须至少有1个其他成员变量。

② sizeof计算含柔性数组的结构体大小时,计算的结果不包含柔性数组的大小,因为柔性数组的大小是未知的。

③ 包含柔性数组的结构体在申请内存空间时要采用动态内存开辟的方式,并且开辟的动态内存空间应大于结构体内存的大小,以适应柔性数组的预期大小(总之,在创建有柔性数组的结构体变量时,不要采用struct St s;传统的方式,这样创建的结构体变量中柔性数组成员变量是没有大小的,我们应采用

struct St* p = (struct St*) malloc(sizeof(struct St)+10* sizeof(int);类似的方式创建结构体变量,找结构体成员变量时直接用(->)操作符即可,这种写法下相当于不同的结构体指针变量,代表着不同的结构体变量)

3. 使用动态内存为含柔性数组的结构体开辟空间的方式,而不用平常为结构体变量开辟空间的方式的好处:① 方便内存释放 ② 访问数组相对较快 ③ 利于减少内存碎片(动态内存之间未利用到的内存)

#include <stdio.h>
#include <stdlib.h>struct St
{float a;int arr[0];
};int main()
{struct St* p = (struct St*)malloc(sizeof(struct St) + 10 * sizeof(int));if (p == NULL){perror("malloc");return 1;}//使用scanf("%f", &(p->a));printf("%f", p->a);for (int i = 0; i < 10; i++){scanf("%d", &(p->arr[i]));printf("%d ", p->arr[i]);}//释放free(p);p = NULL;return 0;
}

 六、C/C++中程序内存区域划分

 

本篇文章已完结,谢谢支持!!! 

相关文章:

【C语言__动态内存管理__复习篇6】

目录 前言 一、动态内存管理 二、动态内存函数 2.1 malloc 2.2 free 2.3 calloc 2.4 realloc 三、动态内存常见的6个使用错误 3.1 接收malloc/calloc返回的参数后未及时检查是否为NULL 3.2 越界访问动态内存空间 3.3 对非动态开辟的内存使用free释放 3.4 使用free只释放了…...

C语言 | Leetcode C语言题解之第30题串联所有单词的子串

题目&#xff1a; 题解&#xff1a; typedef struct {char key[32];int val;UT_hash_handle hh; } HashItem;int* findSubstring(char * s, char ** words, int wordsSize, int* returnSize){ int m wordsSize, n strlen(words[0]), ls strlen(s);int *res (int *)mall…...

大数据dolphinscheduler 本地容器化安装

Minio 容器安装 docker run -p 9000:9000 -p 9090:9090 --name minio -d -e "MINIO_ACCESS_KEYminioadmin" -e "MINIO_SECRET_KEYminioadmin" -v D:\SF\DOCKER\minio\data:/data -v D:\SF\DOCKER\minio\config:/root/.minio minio/minio server /da…...

简单的车牌号识别

目录 处理流程与界面各接口编写时遇到的一些问题上传图片识别结果标签显示中文 处理流程与界面 首先点击“上传图片”按钮&#xff0c;可以选择文件夹中含有汽车车牌的图片&#xff0c;并显示在“图片框”中。 点击“检测车牌”按钮&#xff0c;会先对“图片框”中即含有汽车车…...

openGauss学习笔记-261 openGauss性能调优-使用Plan Hint进行调优-将部分Error降级为Warning的Hint

文章目录 openGauss学习笔记-261 openGauss性能调优-使用Plan Hint进行调优-将部分Error降级为Warning的Hint261.1 功能描述261.2 语法格式261.3 示例261.3.1 忽略非空约束261.3.2 忽略唯一约束261.3.3 忽略分区表无法匹配到合法分区261.3.4 更新/插入值向目标列类型转换失败 o…...

CSS水波纹效果

效果图&#xff1a; 1.创建一个div <div class"point1" click"handlePoint(1)"></div> 2.设置样式 .point1{width: 1rem;height: 1rem;background: #2ce92f;position: absolute;border-radius: 50%;z-index: 999;cursor: pointer;} 3.设置伪…...

迭代器模式:优雅地遍历数据集合

在软件设计中&#xff0c;迭代器模式是一种常见且有用的设计模式&#xff0c;它允许顺序访问一个聚合对象中的各个元素&#xff0c;而又不暴露该对象的内部表示。这种模式在需要对集合进行遍历操作而又不想暴露集合内部结构的场景下非常有用。 一、迭代器模式的使用条件 访问集…...

c++总结笔记(一)

计算机可以将程序转化为二进制指令&#xff08;即机器码&#xff09;&#xff0c;并由CPU执行&#xff0c;CPU会按照指令的顺序依次执行每个指令。 C语言特点&#xff1a; 简洁高效可移植模块化标准化 C语言的标准 C89(C90)标准C99标准C11标准 导入 使用include导入包含…...

[python][gradio]chatbot控件用法

chatbot模块是Gradio中的一个组件&#xff0c;用于展示聊天机器人的输出&#xff0c;包括用户提交的消息和机器人的回复。它支持一些Markdown语法&#xff0c;包括粗体、斜体、代码和图片等。Chatbot模块的输入不接受用户输入&#xff0c;而是通过函数返回的列表来设置聊天内容…...

Sublime Text下载,安装,安装插件管理器,下载汉化插件

SublimeTest官网 © Sublime Text中文网 下载安装 一路点击安装即可 安装插件管理器 管理器官网安装 - 包控制 (packagecontrol.io) 手动安装将3 位置点击网址下载 再打开SublimeTest 点击 选择第一个Browse Packages..... 将会跳转到文件夹中 进入上一个文件夹 在进入…...

c++ ,stl经常出现的<>尖括号其实就是模板类的实例化

通过比如vector<int> 实际上是调用了类似模板template<T t>class vector{...}实例化了一个使用int的vector类来进行定义&#xff0c;我们可以尝试简单的做一个自己的array类 template<typename T1 ,int d2> class array1 {private:T1 *p;int size;public:ar…...

goproxy 简单介绍 及一键安装脚本

goproxy 官网 https://goproxy.cn/ GoProxy 是一项用于 Go 模块的高性能代理服务&#xff0c;旨在为 Go 开发人员提供更快速、更可靠的模块下载体验。它提供以下主要功能&#xff1a; 全球分布式代理服务器: GoProxy 在全球多个地区部署了代理服务器&#xff0c;例如拉斯维加…...

Day13-Python基础学习之数据分析案例

数据分析案例 data_define.py # 数据定义的类 class Record:def __init__(self, date, order_id, money, province):self.date dateself.order_id order_idself.money moneyself.province province ​def __str__(self):return f"{self.date}, {self.order_id}, {se…...

研究生,该学单片机还是plc。?

PLC门槛相对较低&#xff0c;但是在深入学习和应用时&#xff0c;仍然有很高的技术要求。我这里有一套单片机入门教程&#xff0c;不仅包含了详细的视频 讲解&#xff0c;项目实战。如果你渴望学习单片机&#xff0c;不妨点个关注&#xff0c;给个评论222&#xff0c;私信22&am…...

【Java】导出Mysql表表结构与注释数据字典

需求&#xff1a; 把mysql中所有表的字段名、数据类型、长度、注释整理成csv&#xff0c;做成数据字典。 import java.io.IOException; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.sql.ResultSet; import ja…...

第07-2章 TCP/IP模型

7.7 TCP/IP模型详解 7.7.1 简介 应用层的PDU>APDU&#xff08;Application PDU&#xff09; 表示层的PDU>PPDU&#xff08;Presentation PDU&#xff09; 会话层的PDU>SPDU&#xff08;Session PDU&#xff09; 7.7.2 TCP/IP协议体系 &#xff08;1&#xff09;TCP…...

【办公类-21-15】 20240410三级育婴师 712道单选题(题目与答案合并word)

作品展示 背景需求&#xff1a; 前文将APP题库里的育婴师题目下载到EXCEL&#xff0c;并进行手动整理 【办公类-21-13】 2024045三级育婴师 721道单选题 UIBOT下载整理-CSDN博客文章浏览阅读451次&#xff0c;点赞10次&#xff0c;收藏3次。【办公类-21-13】 2024045三级育婴…...

Vue3+Vant开发:登录功能

&#x1f648;作者简介&#xff1a;练习时长两年半的Java up主 &#x1f649;个人主页&#xff1a;程序员老茶 &#x1f64a; ps:点赞&#x1f44d;是免费的&#xff0c;却可以让写博客的作者开心好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全栈&#xff0c;…...

Linux程序调试优化(1)——内存占用详解及优化思路

文章目录 1.free查看总体的内存占用2./proc/$PID/status 查看某进程状态 linux开发最重要的两个参数&#xff0c;分别是内存以及CPU使用率&#xff0c;若内存出现严重不足&#xff0c;则在需要使用内存时&#xff0c;可能出现申请不到的情况&#xff0c;导致 OOM&#xff0c;L…...

高效解决Visual Studio Code中文乱码问题

文章目录 问题解决步骤 问题 Visual Studio Code新建一个文件编码方式总是默认GBK&#xff0c;如果我不修改成默认UTF-8&#xff0c;那么每次运行&#xff0c;如果有中文需要输出就会乱码&#xff01; 解决步骤 之后我会持续更新&#xff0c;如果喜欢我的文章&#xff0c;请记…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日&#xff0c;中天合创屋面分布式光伏发电项目顺利并网发电&#xff0c;该项目位于内蒙古自治区鄂尔多斯市乌审旗&#xff0c;项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站&#xff0c;总装机容量为9.96MWp。 项目投运后&#xff0c;每年可节约标煤3670…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论

路径问题的革命性重构&#xff1a;基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中&#xff08;图1&#xff09;&#xff1a; mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

Git常用命令完全指南:从入门到精通

Git常用命令完全指南&#xff1a;从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?

在工业自动化持续演进的今天&#xff0c;通信网络的角色正变得愈发关键。 2025年6月6日&#xff0c;为期三天的华南国际工业博览会在深圳国际会展中心&#xff08;宝安&#xff09;圆满落幕。作为国内工业通信领域的技术型企业&#xff0c;光路科技&#xff08;Fiberroad&…...

给网站添加live2d看板娘

给网站添加live2d看板娘 参考文献&#xff1a; stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下&#xff0c;文章也主…...