C语言动态内存管理【进阶--5--】
文章目录
- @[toc]
- 动态内存管理
- 一、作用即意义
- 二、动态内存函数的介绍
- Ⅰ、malloc()函数、free()函数
- Ⅱ、calloc()函数
- Ⅲ、realloc()函数
- 三、常见的动态内存错误
- Ⅰ、对NULL指针的解引用操作
- Ⅱ、对动态开辟空间的越界访问
- Ⅲ、对非动态开辟的内存使用free释放
- Ⅳ、使用free释放动态开辟内存的一部分
- Ⅴ、对同一块内存空间多次释放
- Ⅵ、未释放动态开辟的内存(内存泄漏)
- 四、柔性数组
- 柔性数组的使用
文章目录
- @[toc]
- 动态内存管理
- 一、作用即意义
- 二、动态内存函数的介绍
- Ⅰ、malloc()函数、free()函数
- Ⅱ、calloc()函数
- Ⅲ、realloc()函数
- 三、常见的动态内存错误
- Ⅰ、对NULL指针的解引用操作
- Ⅱ、对动态开辟空间的越界访问
- Ⅲ、对非动态开辟的内存使用free释放
- Ⅳ、使用free释放动态开辟内存的一部分
- Ⅴ、对同一块内存空间多次释放
- Ⅵ、未释放动态开辟的内存(内存泄漏)
- 四、柔性数组
- 柔性数组的使用
动态内存管理
一、作用即意义
静态内存分配是在编译时确定的,而动态内存管理是在程序运行时动态的分配和释放内存
动态内存管理允许程序根据需要分配和释放内存
动态内存管理在处理大小未知的数据或在程序执行过程中改变数据结构的情况中非常实用
已学的开辟内存空间的方式
在栈空间上开辟4字节的空间:
int i = 0;
在栈空间上开辟10字节的连续空间:
char arr[10] = { 0 };
以上的空间开辟方式有如下特点:
- 开辟空间的大小是固定的
- 在声明数组时,必须指定数组长度且数组所需要的内存在其编译时分配
二、动态内存函数的介绍
malloc()
:分配指定大小的内存块void *malloc(size_t size);
malloc
函数返回一个指向分配的内存块的指针- 如果分配失败,它会返回
NULL
calloc()
:分配指定数量和大小的内存块,并初始化为零void *calloc(size_t num, size_t size);
calloc
函数返回一个指向分配的内存块的指针,所有字节都被初始化为零- 如果分配失败,它会返回
NULL
realloc()
:重新分配内存块的大小void *realloc(void *ptr, size_t size);
realloc
函数可以增加或减少之前分配的内存块的大小如果
ptr
是NULL
,它的行为类似于malloc
如果分配失败它会返回
NULL
,并且原始内存块保持不变
free()
:释放之前分配的内存void free(void *ptr);
free
函数释放之前通过malloc
、calloc
或realloc
分配的内存- 释放后,指针
ptr
不再指向有效的内存
Ⅰ、malloc()函数、free()函数
malloc()
定义在<stdlib.h>
中用于动态内存分配的函数
函数原型:
void *malloc(size_t size);
size
:需要分配的内存块的大小,单位是字节返回值:
malloc
函数返回一个指向分配的内存块的指针。如果分配成功,返回的指针指向一块至少为size
字节的内存区域- 如果分配失败(通常是因为内存不足),
malloc
返回NULL
free()
定义在<stdlib.h>
中用于释放之前通过malloc
、calloc
或realloc
分配的动态内存的函数
函数原型:
void free(void *ptr);
ptr
:指向要释放的内存块的指针功能:
free
函数释放之前分配的内存块,使其重新成为可用内存,可以被后续的内存分配请求使用注意事项:
- 不应该多次释放同一块内存,多次释放同一块内存可能会导致程序崩溃或内存损坏
free(NULL)
函数将不进行任何操作- 释放内存后,应该将指针设置为
NULL
,以避免野指针问题free()
只能释放动态开辟的空间- 访问或操作已经被
free
释放的内存,会导致未定义行为,致使程序崩溃
使用示例:
#include<errno.h>
#include<string.h>
#include<stdlib.h>int main()
{//动态开辟内存int arr[10] = { 0 };//在栈区申请空间int *p = (int*)malloc(40);//malloc()在堆区申请空间if (p == NULL) {printf("%s\n", strerror(errno));//如果开辟失败则打印错误信息,并返回1return 1;}int i = 0;for (i = 0; i < 10; i++) {*(p + i) = i + 1;}for (i = 0; i < 10; i++) {printf("%d ", *(p + i));}free(p);//释放内存p = NULL;//将指针设置为NULL,避免野指针return 0;
}
-
当程序退出时,系统会自动回收内存空间
-
free
函数需要与相应的内存分配器(如malloc
、calloc
或realloc
)一起使用 -
释放内存后,因及时将指针设置为
NULL
,避免野指针 -
int arr[10] = { 0 };
是在 栈区(Stack) 申请空间,int *p = (int*)malloc(40);
malloc()
是在 堆区(Heap) 申请空间
Ⅱ、calloc()函数
- 定义在
<stdlib.h>
中用于动态内存分配的函数 - 与
malloc()
不同的是,calloc()
在分配内存成功后,会将所有字节都初始化为0
函数原型:
void *calloc(size_t num, size_t size);
num
:要分配的元素数量size
:每个元素的大小,单位是字节返回值:
calloc
函数返回一个指向分配的内存块的指针
- 如果分配成功,返回的指针指向一块至少为
num * size
字节的内存区域,并且所有字节都被初始化为0
- 如果分配失败(通常是因为内存不足),
calloc()
将返回NULL
使用示例:
#include<stdlib.h>int main()
{int* p = (int*)calloc(10, sizeof(int));for (int i = 0; i < 10; i++){printf("%d ", *(p + i));}free(p);//释放内存p = NULL;//将指针设置为NULL,避免野指针return 0;
}
- 输出结果:
0 0 0 0 0 0 0 0 0 0
可以这样认为 :
calloc() = malloc() + memset()
Ⅲ、realloc()函数
-
定义在
<stdlib.h>
中用于动态内存分配的函数 -
realloc()
函数可以在不丢失原有数据的前提下,增加或减少内存块的大小
函数原型:
void *realloc(void *ptr, size_t new_size);
ptr
:指向之前分配的内存块的指针
- 如果
ptr
是NULL
,则realloc
的行为类似于malloc
,即分配一个新的内存块new_size
:新的内存块大小,单位是字节返回值:
realloc
函数返回一个指向调整大小后的内存块的指针
- 如果调整大小成功,返回新内存块的首地址
- 如果调整大小失败(通常是因为内存不足),
realloc
返回NULL
(在这种情况下,原始的内存块保持不变,不会被释放或修改)- 因此不能用原指针来接收
realloc()
函数返回的首地址- 如果
ptr
是NULL
,realloc
将分配一个新的内存块,并返回指向它的指针
原始p指针
和ptr指针
如果
realloc()
之后能够在原有的内存块附近找到足够的空间来扩展内存,它会返回原来的指针(即p
)如果不能,它会在堆上找到足够大的新内存块,将原有数据复制过去,并返回新内存块的地址(即
ptr
)
- 确定
p
和ptr
是否指向同一块内存的步骤:- 比较指针地址:在调用
realloc
之后,检查返回的指针ptr
是否与原始指针p
相等 - 处理不同情况:
- 如果
ptr
等于p
,说明realloc
在原有内存块旁边找到了足够的空间,没有分配新的内存块,因此不需要复制数据- 此时释放内存只需释放
p
,因为p
和ptr
指向同一块内存
- 此时释放内存只需释放
- 如果
ptr
不等于p
,说明realloc
分配了新的内存块,需要将原有数据复制到新的内存块,并释放原始内存块
- 如果
- 比较指针地址:在调用
使用示例:
int main()
{//动态开辟内存int *p = (int*)malloc(40);//malloc()在堆区申请空间if (p == NULL) {printf("%s\n", strerror(errno));//如果开辟失败则打印错误信息,并返回1return 1;}int i = 0;for (i = 0; i < 10; i++)//初始化申请的内存{*(p + i) = i + 1;}//使用realloc扩容int* ptr = (int*)realloc(p, 80);if (ptr == NULL) {// 如果扩容失败,释放原始内存并返回错误free(p);printf("%s\n", strerror(errno));return 1;}if (p == ptr)//如果能够在原有的内存块附近找到足够的空间来扩展内存,返回原来的指针{}else {p = ptr; // 更新p指向扩容后的内存}for (i = 0; i < 10; i++){printf("%d ", *(p + i));}free(p);//p = ptr因此只需释放pp = NULL;return 0;
}
三、常见的动态内存错误
Ⅰ、对NULL指针的解引用操作
int main()
{int* p = (int*)malloc(sizeof(int));*p = 10;return 0;
}
-
如果
malloc()
开辟动态内存失败,则会返回空指针(NULL),此时对p
解引用(*p
)就会发生错误 -
在使用时应加上判断:
-
int main(){int* p = (int*)malloc(sizeof(int));if (p == NULL)return 1;*p = 10;free(p);p=NULL;return 0;}
-
Ⅱ、对动态开辟空间的越界访问
越界访问的例子:
#include <stdio.h>
#include <stdlib.h>int main()
{int* array = malloc(10 * sizeof(int));if (array == NULL) {return 1;}// 初始化数组for (int i = 0; i <= 10; i++) {array[i] = i;//当i=10时,会造成越界访问}free(array);array = NULL;return 0;
}
Ⅲ、对非动态开辟的内存使用free释放
举例:
int main()
{int a = 10;int* p = &a;free(p);//errorreturn 0;
}
Ⅳ、使用free释放动态开辟内存的一部分
即:使用
free()
释放内存时,()
内的参数指针未指向所开辟内存的首地址
举例:
int main()
{int* p = (int*)malloc(40);if (p == NULL)return 1;for (int i = 0; i < 3; i++){*p = i;p++;//改变了p所指向的位置}free(p);//此时的指针p并不指向开辟空间的首地址return 0;
}
Ⅴ、对同一块内存空间多次释放
-
这种错误被称为“双重释放”
(Double Free)
-
当程序试图释放已经释放过的内存时,会发生未定义行为,这可能导致程序崩溃、内存损坏、安全漏洞等问题
避免双重释放:
- 指针置空:释放内存后,将指针立即置为
NULL
free(p); p = NULL;
示例:
#include <stdio.h>
#include <stdlib.h>int main()
{void *p = malloc(10 * sizeof(int));if (p == NULL) return 1;// 使用内存...// 释放内存free(p);p = NULL;// 尝试再次释放,但由于p已经是NULL,所以不会发生双重释放free(p);return 0;
}
Ⅵ、未释放动态开辟的内存(内存泄漏)
示例 1 :
void test()
{int* p = (int*)malloc(40);int n = 0;scanf("%d", &n);if (n == 4)return;free(p);//程序有概率无法到达free处,造成内存泄露p = NULL;
}
int main()
{test();return 0;
}
示例 2 :
int* test()
{int* p = (int*)malloc(40);if (p == NULL)return 1;return p;
}
int main()
{int* ret = test();//未释放会导致内存泄露//free(ret);//ret = NULL;return 0;
}
四、柔性数组
- 柔性数组
(Flexible Array)
是C语言中的一种特性,它允许在结构体的末尾定义一个大小不固定的数组
使用条件:
- 柔性数组必须为结构体的 最后一个成员
- 结构体中必须至少包含一个非柔性数组的成员
- 在结构体中只能存在一个柔性数组
- 编译器需要支持
C99
标准
示例:
typedef struct {int id;int grade;char name[]; // 柔性数组
} S1;
- 在这个例子中,
char name[]
是一个柔性数组,因为它没有指定具体的大小,可以根据需要动态分配内存
注意事项:
sizeof
操作符返回的结构体大小不包括柔性数组的大小- 结构体中必须至少包含一个非柔性数组的成员
- 包含柔性数组成员的结构用
malloc()
函数进行内存的动态分配,并且分配的内存应该大于结构体的大小,以适应柔性数组的预期大小- 使用柔性数组可以减少内存碎片,提高内存利用率,并且使得内存释放更加方便
柔性数组的使用
#include <stdio.h>
#include <stdlib.h>
struct S
{int n;int arr[];//柔性数组成员
};int main()
{//分配内存:结构体的大小加上柔性数组需要的大小struct S* ps = (struct S*)malloc(sizeof(struct S) + 40);if (ps == NULL){//...分配失败return 1;}//赋值ps->n = 10;for (int i = 0; i < 10; i++){ps->arr[i] = i;}//柔性数组扩容struct S* ptr = (struct S*)realloc(ps, sizeof(struct S) + 40 + 12);if (ptr == NULL){//...分配失败return 2;}ps = ptr;//更新指针for (int j = 0; j < 3; j++)//对扩容的内存赋值{ps->arr[10 + j] = 10 + j;}//打印printf("%d\n", ps->n);for (int k = 0; k < 13; k++){printf("%d ", ps->arr[k]);}//释放free(ps);ps = NULL;ptr = NULL;return 0;
}
-
100 1 2 3 4 5 6 7 8 9 10 11 12
-
n
与arr
都存放在堆区,且是连续的内存 -
-
给一个结构体内的数据分配一个连续的内存,优点:
-
- 方便内存释放
-
- 有利于访问速度
-
若不使用柔性数组:
#include <stdio.h>
#include <stdlib.h>struct S
{int n;//大小:4int* arr;//大小:4
};int main()
{struct S* ps = (struct S*)malloc(sizeof(struct S));//sizeof(struct S)结构体的大小不包含if (ps == NULL){//...处理内存分配失败return 1;}ps->n = 10;ps->arr = (int*)malloc(40);//分配10个int的空间if (ps->arr == NULL){//...处理内存分配失败return 1;}//使用for (int i = 0; i < 10; i++)//初始化数组ps->arr[i] = i;//打印printf("%d \n", ps->n);for (int i = 0; i < 10; i++)printf("%d ", ps->arr[i]);free(ps->arr);ps->arr = NULL;free(ps);ps = NULL;return 0;
}
-
100 1 2 3 4 5 6 7 8 9
-
虽然
n
与arr
都存放在堆区,但并不连续 -
-
不使用柔性数组会产生较多的内存碎片,且释放内存相较复杂
C语言结构体里的成员数组和指针 | 酷 壳 - CoolShell
相关文章:
C语言动态内存管理【进阶--5--】
文章目录 [toc] 动态内存管理一、作用即意义二、动态内存函数的介绍Ⅰ、malloc()函数、free()函数Ⅱ、calloc()函数Ⅲ、realloc()函数 三、常见的动态内存错误Ⅰ、对NULL指针的解引用操作Ⅱ、对动态开辟空间的越界访问Ⅲ、对非动态开辟的内存使用free释放Ⅳ、使用free释放动态开…...
Hadoop其四,片与块,MapReduce原理,Shuffle过程,Combiner
目录 一、关于片和块 二、MapReduce的原理 MapTask执行阶段 ReduceTask的执行流程: 三、Shuffle 过程 map端: reduce端: 环形缓冲区: 四、Combiner 【可有可无】 五、需要记忆的内容 一、关于片和块 假如我现在500M这样…...
引领未来的变革:15种前沿RAG技术及其应用探索
在现代人工智能领域,检索增强生成(RAG)技术逐渐成为推动各种应用的重要力量。这些技术通过结合信息检索与文本生成,能够更有效地处理和利用信息。本文将详细介绍15种前沿RAG技术及其具体应用实例,以帮助您更好地理解这…...
gradle在IDEA 中无法使用的启动守护线程的问题
最近打开一个比较早的项目,Gradle 配置没有问题,IDEA 打开Java项目却不能初始化守护线程,UI 上只能看到失败,看不到具体原因。 首先尝试了升级最新的gradle 版本8.11, 实际上这个版本在本地命令行都不能正常工作,没有…...
C++小白实习日记——Pollnet,Efvi,UDP,数据类型转换(上)
上周主要是熟悉了一下公司内部一些自定义结构体对应的数据类型,要求:读取文件,将文件中数据转化为定义的结构体中的数据类型,按照时间进行排序,用UDP发送数据;在另一台服务器上接收数据,按照定义…...
git安装教程(Git-2.38.1-64-bit)
目录 一、git下载 二、git安装 1.更改安装路径 2.安装组件 3.选择开始菜单文件夹 4.选择Git默认编辑器 5.决定初始化新项目(仓库)的主干名字 6.修改Git的环境变量 7.选择SSH执行文件 9.选择HTTPS后端传输 10.配置行尾符号转换 11.配置终端模…...
C# OpenCvSharp DNN 实现百度网盘AI大赛-表格检测第2名方案第三部分-表格方向识别
目录 说明 效果 模型 项目 编辑 代码 参考 下载 其他 说明 百度网盘AI大赛-表格检测的第2名方案。 该算法包含表格边界框检测、表格分割和表格方向识别三个部分,首先,ppyoloe-plus-x 对边界框进行预测,并对置信度较高的表格边界…...
selenium 验证码滑块对齐没有验证通过
描述: 最近使用seleniuim采集有滑块验证码的数据,遇到了移动滑块对齐后,还是无法通过验证,经过模拟真人多次移动、控制移动时间(避免过快)一番尝试后、最终通过模拟抖动得以解决 解决办法: 把yoffset的值改为-6~6的…...
【Neo4J】neo4j docker容器下的备份与恢复
文章目录 一. 官网说明1. 操作说明2. 注意事项 二. docker 容器化操作1. 导出(备份)停止容器执行备份 2. 导入(恢复)停止容器(如果未停止)执行导入 3. 启动容器 一. 官网说明 https://neo4j.com/docs/operations-manual/current/…...
Java实现雪花算法获取id
Java实现雪花算法获取id 在 Java 中实现雪花算法(Snowflake)时,通常会设计一个工具类来生成全局唯一的 ID。这个工具类可以封装雪花算法的逻辑,并提供简单的接口来生成 ID。 以下是一个完整的 Java 工具类实现雪花算法的例子&am…...
Leetcode1338:数组大小减半
题目描述: 给你一个整数数组 arr。你可以从中选出一个整数集合,并删除这些整数在数组中的每次出现。 返回 至少 能删除数组中的一半整数的整数集合的最小大小。 代码思路: 这个代码的目的是解决一个特定的问题:给定一个整数数…...
【系统思辨】分散注意
注意力在我们的日常生活和工作中扮演着至关重要的角色。注意力可以提高效率和准确性、减少错误和失误,提升学习效率,促进创造力。与此同时,各种各样的生活事件在分散我们的注意力,并且还有很多分散我们注意的手段,比如…...
微信小程序中 Echarts 的巧妙运用
一、引入 Echarts 的准备工作 在微信小程序中引入 Echarts 需要进行一系列的准备工作。首先,我们可以从 echarts 官网或 GitHub 上下载 echarts-for-weixin 项目。找到其中的 ec-canvas 文件夹,这个文件夹将是我们引入到微信小程序项目中的关键部分。 …...
opencv——图片矫正
图像矫正 图像矫正的原理是透视变换,下面来介绍一下透视变换的概念。 听名字有点熟,我们在图像旋转里接触过仿射变换,知道仿射变换是把一个二维坐标系转换到另一个二维坐标系的过程,转换过程坐标点的相对位置和属性不发生变换&a…...
Gate学习(7)引入体素源
一、从GitHub下载体素源模型源码 下载地址:BenAuer2021/Phantoms-for-Nuclear-Medicine-Imaging-Simulation:用于核医学成像应用的模型(闪烁显像、SPECT 和 PET) --- BenAuer2021/Phantoms-For-Nuclear-Medicine-Imaging-Simulat…...
腾讯微信Android面试题及参考答案(多张原理图)
Android 应用的启动流程如下: 当用户点击应用图标时,首先会通过 Launcher(桌面启动器)来响应这个操作。Launcher 本身也是一个 Android 应用,它运行在系统中,负责管理和显示桌面上的图标等信息。 系统会检查应用是否已经有进程存在。如果没有,就会通过 Zygote 进程来孵化…...
【Android】View的工作流程
View的工作流程 开始了解一下View的工作流程,就是measure、layout和draw。measure用来测量View的宽高,layout用来确定View的位置,draw则用来绘制View。这一讲我们来看看measure流程,measure流程分为View的measure流程和ViewGroup…...
Linux基础指令
使用 tab 键补全 我们敲的所有的 Linux 命令 , 都可以使用 tab 键来尝试补全 , 加快效率 . 使用 ctrl c 重新输入 如果命令或者目录敲错了 , 可以 ctrl c 取消当前的命令 . ls :列出当前目录中的文件和子目录 语法 : ls [ 选项 ] [ 目录或文…...
Gemini 2.0 Flash重磅发布:多模态AI大模型,赋能实时交互与智能助手新体验
点击访问 chatTools 免费体验GPT最新模型,包括o1推理模型、GPT4o、Claude、Gemini等模型! 在AI领域竞争日益激烈的今天,谷歌再次亮剑,推出了新一代至强AI大模型——Gemini 2.0 Flash。这款模型不仅具备强大的多模态输入输出能力&a…...
项目十二 杜甫作品问卷
【项目目标】 理解网格系统的原理。理解媒体查询的工作原理。【項目内容】 使用网格系统进行响应式网页设计。运用媒体查询对不同类型的设备应用不同的样式。【项目步骤】 Bootstrap 框架资源既可以直接从 CDN 服务商服务器中引入,也可以加入本地素材文件夹中给出的资…...
7_Sass Introspection 函数 --[CSS预处理]
Sass 的 Introspection 函数允许开发者检查和操作样式表的内部结构,包括选择器、属性、值等。这些函数提供了对编译过程中 Sass 文件内容的深入访问能力,使得更复杂的逻辑处理成为可能。以下是一些常用的 Sass Introspection 函数及其用法示例࿱…...
Qt:Q_GLOBAL_STATIC实现单例(附带单例使用和内存管理)
转载 https://blog.csdn.net/m0_71489826/article/details/142288179 前言 本文主要写Q_GLOBAL_STATIC实现单例以及单例的释放,网上很多教程只有单例的创建,但是并没有告诉我们单例的内存管理,这就很头疼。 正文 使用 Qt 的 Q_GLOBAL_STA…...
HTML/CSS总结
HTML 1.1 标题标签h 为了使网页更具有语义化,我们经常会在页面中用到标题标签,HTML提供了6个等级的标题,即 标题标签语义: 作为标题使用,并且依据重要性递减 其基本语法格式如下: <h1> 标题文本…...
字符串性能对比
效率(1) : String.indexOf与String.contains效率测试_string contains效率-CSDN博客 结论是前者效率高,源码里面conatins是使用indexof 在jdk8中contains直接调用的indexOf(其他版本没有验证),所以要说效率来说肯定是indexOf高,但contains也就多了一层方法栈,so 什…...
【漫话机器学习系列】005.神经网络的结构(architecture on the neural network)
神经网络(Neural Network)是一种模拟人脑神经系统的计算模型,由大量相互连接的神经元(节点)组成,广泛应用于深度学习和机器学习领域。以下是神经网络的基本结构及关键组成部分。 1. 神经网络的基本组成 一…...
关卡选择与布局器
unity布局管理器 使用unity布局管理器轻松对关卡选择进行布局。 实现过程 准备普通按钮button设置字体和对应的sprite设置父gameobject(levelbase) 再创建UI.image(selectbackground)布局背景和大小gameobject(grid…...
数据分析实战—房价特征关系
1.实战内容 (1) 读取房价特征关系表(house_price.npz)绘制离地铁站的距离与单位面积的房价的散点图,并对其进行分析; import pandas as pd import numpy as np import warnings warnings.filterwarnings(&…...
@ResponseBody详解
ResponseBody 是 Spring Framework 中的一种注解,用于表示返回的内容应该直接写入 HTTP 响应体,而不是通过视图解析器来渲染一个视图(如 JSP 页)。当你在控制器的方法上使用 ResponseBody 时,Spring 会将方法的返回值直…...
Harmony Next开发通过bindSheet绑定半模态窗口
示例概述 Harmony Next开发通过bindSheet绑定半模态窗口 知识点 半模态窗口父子组件传值 组件 LoginComponent Component struct LoginComponent {// Prop 父子单项绑定值Prop message:string // Link 父子双向绑定值Link userName:stringLink password:stringLink isSh…...
Redis--高并发分布式结构
目录 一、引言 二、redis 1.什么是redis? 三、基础概念 1.什么是分布式? 2.应用服务和数据库服务分离 3.负载均衡 4.分库分表 5.微服务架构 四、总结 一、引言 本篇文章就简单介绍一下什么是redis,以及一些关于高并发和分布式结构的…...
Day38 动态规划part06
322. 零钱兑换 如果求组合数就是外层for循环遍历物品,内层for遍历背包。 如果求排列数就是外层for遍历背包,内层for循环遍历物品。 这句话结合本题 大家要好好理解。 视频讲解:动态规划之完全背包,装满背包最少的物品件数是多少?| LeetCode:322.零钱兑换_哔哩哔哩_bilib…...
1.1 类型(types)
源码 types.rs文件源码: use euclid::{Point2D, Vector2D};//引用外部泛型/// 绘图中所有事物所使用的笛卡尔坐标系。The cartesian coordinate system used by everything in a drawing. #[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd)] pub enu…...
PyTorch如何通过 torch.unbind 和torch.stack动态调整张量的维度顺序
笔者一篇博客PyTorch 的 torch.unbind 函数详解与进阶应用:中英双语中有一个例子如下: # 创建一个 3x2x2 的三维张量 x torch.tensor([[[1, 2], [3, 4]],[[5, 6], [7, 8]],[[9, 10], [11, 12]]])# 第一步:沿第 0 维分解为 3 个 2x2 张量 un…...
在 Node.js 中安装和使用 TensorFlow.js 的完整指南
在 Node.js 中安装和使用 TensorFlow.js 的完整指南 简介 TensorFlow.js 是一个开源的机器学习库,它允许在 JavaScript 环境中进行机器学习模型的开发和训练。本文将介绍如何在 Node.js 环境中安装和配置 TensorFlow.js。 环境准备 在开始之前,请确保…...
ubuntu 下如何查看用户的最近登录的时间
在 Ubuntu 系统下,可以通过以下几种方式查看用户最近的登录时间: 方法 1: 使用 last 命令 last 命令会显示系统上用户的登录记录,包括时间和来源。 last 用户名 例如,要查看用户 test 的最近登录记录: last test …...
Linux下调试工具:gdb
Windows和Linux下的调试有区别吗? 调试思路上一定是一样的;调试的操作方式有差别(Linux命令行调试,Windows窗口) 1.准备工作: 默认情况下,gdb无法进行对现在发布的程序进行调试(debug / release)。在Linux下用gcc编译…...
metagpt 多智能体系统
metagpt 多智能体系统 代码1. 动作及角色定义2. 主函数 代码解释1. 导入模块:2. 环境设置:3. 定义行动(Action):4. 定义角色(Role):5. 学生和老师的行为:6. 主函数&#…...
Python中opencv的一些函数及应用
Sobel 算子函数 功能: Sobel 算子用于计算图像的梯度(变化率),常用于边缘检测。它通过对图像应用一个基于一阶导数的滤波器来强调图像中的边缘部分,特别是水平和垂直方向上的边缘。通过计算图像的梯度,可以…...
泷羽sec学习打卡-brupsuite8伪造IP和爬虫审计
声明 学习视频来自B站UP主 泷羽sec,如涉及侵权马上删除文章 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都 与本人无关,切莫逾越法律红线,否则后果自负 关于brupsuite的那些事儿-Brup-FaskIP 伪造IP配置环境brupsuite导入配置1、扩展中先配置python环境2、安…...
麒麟信安推出支持信创PC的新一代云桌面方案,助力政务信创高效安全运维
12月11日,在第二届国家新一代自主安全计算系统产业集群融通生态大会上,麒麟信安发布了支持信创PC的新一代云桌面方案,该方案是基于国际TCI架构实现国产PC机云化纳管在国内的首次发布,并与银河麒麟桌面操作系统、长城国产PC整机实现…...
【我的开源】ESCurlGen 一款 ElasticSearch curl 命令生成器
由于经常编写复杂的 Elasticsearch 查询,并通过代码生成查询条件,我发现每次使用 curl 请求 Elasticsearch 时,手动复制配置信息并构建 curl 命令的过程非常繁琐,尤其是在管理多个环境的情况下更为不便。因此,我利用 A…...
基于ESP32的桌面小屏幕实战[4]:硬件设计之PCB Layout
1. PCB Layout 步骤 生成PCB 确定PCB layout规范 绘制板框尺寸 布局 布局规范: 按电气性能合理分区,一般分为:数字电路区(即怕干扰、又产生干扰)、模拟电路区(怕干扰)、功率驱动区(干扰源)&a…...
(css)element中el-select下拉框整体样式修改
(css)element中el-select下拉框整体样式修改 重点代码(颜色可行修改) // 修改input默认值颜色 兼容其它主流浏览器 /deep/ input::-webkit-input-placeholder {color: rgba(255, 255, 255, 0.50); } /deep/ input::-moz-input-placeholder {color: rgba…...
金融分析-Transformer模型(基础理论)
Transformer模型 1.基本原理 transformer的core是注意力机制,其本质就是编码器-解码器。他可以通过多个编码器进行编码,再把编码完的结果输出给解码器进行解码,然后得到最终的output。 1.1编码器 数据在编码器中会经过一个self-attention的…...
Parcel 常用插件:增强功能与性能的最佳选择
前言 Parcel 是一个现代化的零配置应用打包工具,旨在简化开发流程并提高效率。通过其智能的默认配置和丰富的插件生态系统,Parcel 使得开发者能够轻松应对各种构建需求。虽然 Parcel 在大多数情况下可以开箱即用,但为了满足特定的项目需求&a…...
Vite 与 Webpack 的区别
在前端开发中,构建工具是不可或缺的,Webpack 和 Vite 是当前最流行的选择之一。尽管它们的目标相似,但在实现方式和开发体验上却有显著差异。本文将探讨 Vite 和 Webpack 的主要区别,以便于根据项目需求选择合适的工具。 1. 构建…...
服务器ubuntu重装系统后将原来的用户进行关联
服务器ubuntu重装系统后将原来的用户数据进行关联 关联用户到已存在目录 sudo useradd user_name -m -s /bin/bash -d /home***/name添加sudo权限 vim /etc/sudoers# 文件末尾添加 user_name ALL(ALL:ALL) ALL更改拥有者 sudo chown -R user_name:user_name /home***/na…...
Python模块导入:import与from...import的深度解析
Python模块导入:import与from…import的深度解析 在Python编程中,模块的导入是组织和复用代码的关键环节。Python提供了import和from...import两种常见的模块导入方式,它们在使用方式、命名空间管理、可读性、内存使用等方面各有特点&#x…...
ROS2-humble中指定OpenCV版本进行开发
本地是Ubuntu22.04系统,安装了ROS2-humble,看了下humble自带的OpenCV版本4.5.4,由于DNN模块读取.onnx格式的模型要用OpenCV4.7及以上的版本,于是编译了4.10.0的OpenCV,但开发ROS2节点时,虽然CMake中已经指定…...
如何在 Ubuntu 22.04 上使用 vnStat 监控网络流量
简介 vnStat是一个免费的、开源的、基于控制台的Linux操作系统网络流量监控工具。通过vnStat,你可以在不同的时间段监控网络统计数据。它简单、轻量级,并且消耗的系统资源很小。vnStat允许你按小时、日、月、周和日生成网络流量数据。本教程将向你展示如…...