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

内存函数和动态内存管理

目录

一、memcpy库函数介绍

1. memcpy的使用

2. memcpy的模拟

二、memmove库函数介绍

1. memmove的使用

2. memmove的模拟

三、memset库函数介绍

四、memcmp库函数介绍

五、动态内存中malloc和free

1. malloc

2. free

六、动态内存中calloc和realloc

1. calloc

2. realloc

七、柔性数组

1.1 柔性数组特点

1.2 柔性数组的使用

1.3 柔性数组与结构体内部成员指针区别

八、动态内存中使用常见错误

1. 对NULL指针的解引⽤操作

2. 对动态开辟空间的越界访问

3. 对⾮动态开辟内存使⽤free释放

4. 使⽤free释放⼀块动态开辟内存的⼀部分

5. 对同⼀块动态内存多次释放

6. 动态开辟内存忘记释放(内存泄漏)

九、关于动态内存易错例题

1. 题目一

2. 题目二

3. 题目三

4. 题目四

十、总结c/c++中程序内存区域划分图


一、memcpy库函数介绍

1. memcpy的使用

        memcpy这个库函数用于是任何类型,将一个地址的内容复制到到另一个地址上,它是针对于内存的修改,使用使用过程中是memcpy(arr1(拷贝地址),arr2(从这里抄内容到arr1中),size_t(字节个数)),需要头文件string.h返回的是arr1这个已经拷贝的地址

它遇到\0不会停止,它只受字节个数的影响,它针对的是内存的修改,也就是一个一个字节的修改。注意这里是适用于不重叠的内存

2. memcpy的模拟

        根据以上的信息,可以知道memcpy的修改是通过一个一个字节的修改而以小改大。

#include<stdio.h>
void* my_memcpy(void* dest, const void* src, size_t num)
{char* ret = dest;//记入起始地址//拷贝while (num--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;//void*类型不能改变值,需要强制类型转换src = (char*)src + 1;}return ret;
}
int main()
{int arr1[20];int arr2[] = { 0,1,2,3,4,5,6,7 };void* ret = my_memcpy(arr1, arr2, sizeof(int) * 5);for (int i = 0; i <  5; i++){printf("%d ", ((int*)ret)[i]);}return 0;
}

 

二、memmove库函数介绍

1. memmove的使用

        memmove和memcpy的使用是一样的,不过它专门用于重叠内存的拷贝。

2. memmove的模拟

        menmove的情况就比较多了,因为对于重叠的内存,那就得考虑第一种是与需要拷贝字节内有重叠部分,这时候就是类型指针用于放入拷贝的内容地址比另一个指针类型用于输s出内容到拷贝指针小(也就是改变后,对后面拷贝没有影响第二种就是需要拷贝的字节内容有重叠部分,此时类型指针用于放入拷贝的内容地址比另一个指针类型用于输出内容到拷贝指针大(也就是改变后,对后面拷贝有影响)第三种就是拷贝字节不重叠(完全错开),这个是较为简单。直接上图来解释

#include<stdio.h>
#include<assert.h>
void* my_memmove(void* dest, void* src, size_t num)
{assert(dest && src);void* ret = dest;//记入起始//判断重叠条件//第一种和第三种的一部分,从前往后直接替换即可if (dest < src){while (num--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;//一个一个字节改变src = (char*)src + 1;}}//第二种和第三种的一部分,从后到前else{while (num--){*((char*)dest + num) = *((char*)src + num);//一步到位,用num来控制循环,还能使得从后到前改变每个字节//这里要注意的是一开始加的是19,而不是20,所以这里是num--}}return ret;
}
int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,0 };void* ret = my_memmove(arr + 2, arr, sizeof(int) * 5);return 0;
}

 

对比memmove,模拟出来的恰好的正确的。这里需要注意的就是num--,为什么要这样设计。 

三、memset库函数介绍

        memset虽然是内存的修改,但是对于整型修改时,可能会不符合预期,memset的使用格式为(void*)memset(void*(地址),int(修改值字符或者数字),size_t(需要修改的字节个数))返回的是修改后的起始地址。上面也说了,memset是一个一个字节的修改对于要修改的值,所以对于数字整型4个字节的修改时,就不会符合预期。

每个字节都会修改成1,而读取整型时是通过4个字节4个字节的读取的,所以这里数字就会0x01010101 这16进制数字将会是很大的数,一般我们修改整型时是将其改为0。不过这里对于是一个字节类型,就没有影响,修改为什么值就是什么值。

四、memcmp库函数介绍

        memcmp是用来对比内存中对应的数字大小(这里字符也是数字,因为字符在内存中是以ascll值存储的),用法就是(int)memcmp(void* prt1,void* prt2,size_t(需要对比的字节个数))


#include<stdio.h>
#include<string.h>
int main()
{int arr1[] = { 1,2,3,4,5 };int arr2[] = { 1,2,3,4,0x80000001 };//这里以小端存储,所以这里在内存存储是0x01 00 00 80//实际打印时还是打印出0x80 00 00 01int r = memcmp(arr1, arr2, 17);if (r > 0){printf("arr1 > arr2\n");}else if (r < 0){printf("arr1 < arr2\n");}else{printf("arr1 == arr2\n");}return 0;
}

这里是最好反映出memcmp的内部比较的形式,这里是以小端存储。对整型在内存的存储有兴趣的可以看这里 

☞ 整数和浮点数在内存中的存储-CSDN博客

五、动态内存中malloc和free

1. malloc

        malloc这个库函数是用与分配空间内存,需要头文件stdlib.h,用法为(void*)malloc (size_t(申请字节))这里申请成功返回该空间的起始地址,如果申请失败则返回空指针,这里分配的是连续可用的空间。

#include<stdio.h>
#include<stdlib.h>
int main()
{//开辟空间int* p = (int*)malloc(sizeof(int) * 10);if (p == NULL){perror("malloc");return 1;}//使用空间for (int i = 0; i < 10; i++){p[i] = i + 1;}for (int i = 0; i < 10; i++){printf("%d ", p[i]);}//释放空间free(p);p = NULL;return 0;
}

2. free

        这里free这个用法很简单,就是用来释放空间的函数,就好比图书馆借书,借了书肯定是要换的,这里开辟空间就类似借书这个过程,还书就是释放空间。(void) free(void* prt)内部是指向需要释放内存的这个空间,而prt指的是这个需要释放内存的这个空间的起始地址。这里必须是开辟的空间,否则会报错,如果释放的是空指针,那什么free什么都不做。

这里需要注意的是free释放完后,要养成一个好习惯,就是将这个指针变为空指针,因为后续如果要使用时,直接使用,那就是野指针的泛滥了。

六、动态内存中calloc和realloc

1. calloc

        calloc这个库函数和malloc这个类似,也是开辟空间的一个库函数,格式有所不同,就是(void*) calloc((元素个数),size_t(一个元素的字节)),都是开辟空间,只不过calloc开辟一个空间后是有自己的初始化内容的,这个初始化内容全为0;要说还有一个不一样的就是语法格式吧,malloc直接就是申请字节个数,而calloc是需要知道什么类型,该类型需要多少个元素。

#include<stdio.h>
#include<stdlib.h>
int main()
{int* p1 = (int*)calloc(10, sizeof(int));if (p1 == NULL){perror("calloc");return 1;}//使用空间//释放空间free(p1);p1 = NULL;return 0;
}

左图为calloc这个库函数开辟的空间,右边为malloc这个库函数开辟的空间。 

2. realloc

        realloc这个用于扩容或缩减内存的大小,可以看需求给他增减空间大小,用法(void*)realloc((void*prt)表示需要扩容或缩减的地址,(size_t)表示扩容或者缩减后的大小)。如果扩容成功则会返回扩容成功后的起始地址并拷贝了扩容之前地址的内容,如果扩容缩减失败则会返回NULL空指针。这里扩容有2种情况

#include<stdio.h>
#include<stdlib.h>
int main()
{//开辟空间int* p = malloc(sizeof(int) * 5);if (p == NULL){perror("malloc");return 1;}//使用空间for (int i = 0; i < 5; i++){p[i] = i + 1;}//不够扩容int* prt = (int*)realloc(p, sizeof(int) * 10);if (prt != NULL){p = prt;//将扩容的地址赋给p(这里主要是怕第二种情况)prt = NULL;}else{perror("realloc");return 1;}//使用//释放空间free(p);p = NULL;return 0;
}

realloc也可以实现malloc功能,realloc(NULL,40)等价于开辟40个字节空间,返回开辟后的空间。 这里如果是缩减空间,缩减过多可能会导致某个溢出字节数据丢失。

七、柔性数组

1.1 柔性数组特点

        柔性数组是指结构体中成员最后一项为一个数组并且还要是未知数组(没有[]大小),特点为:不参与整个结构体的大小前提是还没给它开辟空间。就是整个结构体大小不算这个数组大小)。

#include<stdio.h>
struct Stu1
{int age;char name;
};
struct Stu2
{int age;char name;int arr[];
};
int main()
{printf("%zd\n", sizeof(struct Stu1));printf("%zd\n", sizeof(struct Stu2));return 0;
}

 

1.2 柔性数组的使用

        柔性数组的使用一般配合动态内存函数一起使用,可以随时动态改变所需的大小,一般开辟空间大于结构体总大小,

#include<stdio.h>
#include<stdlib.h>
struct Stu
{int age;char name;int num[];
};
int main()
{//开辟空间struct Stu* s1 = (struct Stu*)malloc(sizeof(struct Stu) + sizeof(int) * 5);if (s1 == NULL){perror("malloc");return 1;}//使用s1->age = 18;s1->name = 'A';for (int i = 0; i < 5; i++){s1->num[i] = i + 1;}//空间不够struct Stu* ps = (struct Stu*)realloc(s1, sizeof(struct Stu) + sizeof(int) * 10);if (ps == NULL){perror("realloc");return 1;}//继续使用for (int i = 5; i < 10; i++){ps->num[i] = i + 1;}//释放free(ps);free(s1);s1 = NULL;ps = NULL;return 0;
}

1.3 柔性数组与结构体内部成员指针区别

        直接代码展示结构体内部成员为指针是如何和柔性数组一样操作的。

#include<stdio.h>
#include<stdlib.h>
struct Stu
{int age;char name;int* arr;
}*s1;
int main()
{//开辟s1 = (struct Stu*)malloc(sizeof(struct Stu));if (s1 == NULL){perror("malloc1");return 1;}//使用s1->age = 18;s1->name = 'A';s1->arr = (int*)malloc(sizeof(int) * 5);//申请if (s1->arr == NULL){perror("malloc2");return 1;}//使用for (int i = 0; i < 5; i++){s1->arr[i] = i + 1;}//扩容int* prt = (int*)realloc(s1->arr, sizeof(int) * 10);if (prt == NULL){perror("realloc");return 1;}else{s1->arr = prt;prt = NULL;}//使用//释放free(s1->arr);//先释放内部再释放外部s1->arr = NULL;free(s1);s1 = NULL;return 0;
}

一般我们都是使用柔性数组,这种用指针的代码量太大了,而且需要开辟两个连续的空间,合起来就不连续,会造成很多内存碎片(表示开辟空间过多,介于两个连续空间内部剩余的空间为内存碎片)。柔性数组的优点就是1.内存释放过程中方便,不像指针需要释放两次,而且还有顺序可言。2.有利于内存访问(连续内存便于访问)。 

八、动态内存中使用常见错误

1. 对NULL指针的解引操作

        开辟空间时,如果不判断是否为空指针,并且阻断后面进程,那就会报警告。

#include<stdio.h>
#include<stdlib.h>
int main()
{int* p = (int*)malloc(sizeof(int) * 5);if (p == NULL){return 1;//必要性,否则会报错}//使用//释放free(p);p = NULL;return 0;
}

2. 对动态开辟空间的越界访问

        对于已经开辟的空间,使用了未开辟的空间,会导致越界访问。

#include<stdio.h>
#include<stdlib.h>
int main()
{//开辟int* p = (int*)malloc(sizeof(int) * 10);if (p == NULL){perror("malloc");return 1;}//使用for (int i = 0; i <= 10; i++){*(p + i) = i + 1;//i=10时越界了}for (int i = 0; i <= 10; i++){printf("%d ", p[i]);}//释放free(p);p = NULL;return 0;
}

3. 对⾮动态开辟内存使⽤free释放

        对于不是动态函数开辟的内存,使用free释放,会导致程序错误。

#include<stdio.h>
#include<stdlib.h>
int main()
{int arr[10] = { 0 };int* p = (int*) & arr;free(p);p = NULL;return 0;
}

 

4. 使⽤free释放⼀块动态开辟内存的⼀部分

        我们知道free(*p)括号里面指向的是开辟空间,而p是开辟空间的起始地址,而释放一部分地址,也会导致程序错误,不能正常工作。

#include<stdio.h>
#include<stdlib.h>
int main()
{int* p = (int*)malloc(sizeof(int) * 5);if (p == NULL){perror("malloc");return 1;}p++;free(p);p = NULL;return 0;
}

5. 对同⼀块动态内存多次释放

        对一个已经开辟的动态内存多次释放。

#include<stdio.h>
#include<stdlib.h>
int main()
{//开辟int* p = (int*)malloc(sizeof(int) * 5);if (p == NULL){perror("malloc");return 1;}//使用//释放free(p);free(p);p = NULL;return 0;
}

6. 动态开辟内存忘记释放(内存泄漏)

        在函数中开辟空间,如果不释放空间并且不返回该空间起始地址,会导致这一块空间浪费,既不能使用,也不能再次开辟这一块空间。

#include<stdio.h>
#include<stdlib.h>
void test()
{int* p = (int*)malloc(sizeof(int) * 5);if (p == NULL){perror("malloc");p = NULL;}//忘记释放
}
int main()
{test();return 0;
}

九、关于动态内存易错例题

1. 题目一

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void GetMemory(char* p)
{p = (char*)malloc(100);//1.没有对NULL解引判断用//2.内存泄漏(没有释放空间)
}
void Test(void)
{char* str = NULL;GetMemory(str);//这里是传值调用strcpy(str, "hello world");//str为空指针printf(str);
}
int main()
{Test();return 0;
}

根据错误信息修改:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void GetMemory(char** p)
{*p = (char*)malloc(100);if (*p == NULL)//判断{perror("malloc");return;}
}
void Test(void)
{char* str = NULL;GetMemory(&str);//传址strcpy(str, "hello world");printf(str);free(str);//释放str = NULL;
}
int main()
{Test();return 0;
}

2. 题目二

#include<stdio.h>
#include<stdlib.h>
char* GetMemory(void)
{char p[] = "hello world";//函数中的局部变量在栈区离开后,会释放内存return p;
}
void Test(void)
{char* str = NULL;str = GetMemory();//str已经改变//但是使用过程中会变为野指针printf(str);
}
int main()
{Test();return 0;
}

3. 题目三

#include<stdio.h>
#include<stdlib.h>
#include<string.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;
}

4. 题目四

#include<stdio.h>
#include<stdlib.h>
#include<string.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;
}

十、总结c/c++中程序内存区域划分图

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

相关文章:

内存函数和动态内存管理

目录 一、memcpy库函数介绍 1. memcpy的使用 2. memcpy的模拟 二、memmove库函数介绍 1. memmove的使用 2. memmove的模拟 三、memset库函数介绍 四、memcmp库函数介绍 五、动态内存中malloc和free 1. malloc 2. free 六、动态内存中calloc和realloc 1. calloc 2. realloc 七、…...

计算机网络 - 在浏览器中输入 URL 地址到显示主页的过程?

第一步&#xff0c;浏览器通过 DNS 来解析 URL&#xff0c;得到相应的 ip 地址&#xff08;到哪里找) 和 方法&#xff08;做什么&#xff09; 第二步&#xff0c;浏览器于服务器建立 TCP 三次握手连接 第三步&#xff0c;建立好连接后&#xff0c;浏览器会组装 HTTP 请求报文…...

Android Studio 常见报错

错误提示&#xff1a; Your build is currently configured to use incompatible Java 21.0.3 and Gradle 6.7.1. Cannot sync the project. 原因&#xff1a; Java JDK和gradle 版本不匹配 两个角度修改&#xff1a; 1.修改gradle 版本 2.修改JDK版本 Gradle 下载 https:…...

RT-DETR源码学习bug记录

事情是这样的&#xff0c;我最近想学习RT-DETR的源码&#xff0c;那就开始吧&#xff01; 1. 找到官网&#xff0c;找到pytorch版本。 https://github.com/lyuwenyu/RT-DETR/tree/main 2.只想下载一个子目录&#xff0c;方法&#xff1a; https://download-directory.githu…...

数据仓库分层架构解析:从理论到实战的完整指南​​

数据仓库分层是构建高效数据体系的核心方法论。本文系统阐述ODS、DWD、DWS、ADS四层架构的设计原理&#xff0c;结合电商用户行为分析场景&#xff0c;详解各层功能及协作流程&#xff0c;并给出分层设计的原则与避坑指南&#xff0c;帮助读者掌握分层架构的落地方法。 一、为什…...

基于ubuntu24.10安装NACOS2.5.1的简介

基于ubuntu24.10安装NACOS2.5.1的简介 官方网站地址&#xff1a; https://nacos.io 可访问nacos站点 https://nacos.io/zh-cn/ 2025年04月记录发布 V2.5.1 版本 一、环境预准备 64 bit JDK 1.8&#xff1b; sudo apt update sudo apt install openjdk-8-jdk sudo apt upda…...

【Triton 教程】triton_language.full

Triton 是一种用于并行编程的语言和编译器。它旨在提供一个基于 Python 的编程环境&#xff0c;以高效编写自定义 DNN 计算内核&#xff0c;并能够在现代 GPU 硬件上以最大吞吐量运行。 更多 Triton 中文文档可访问 →https://triton.hyper.ai/ triton.language.full(shape, …...

MARA/MARC表 PSTAT字段

最近要开发一个维护物料视图的功能。其中PSTAT字段是来记录已经维护的视图的。这里记录一下视图和其对应的字母。 MARA还有个VPSTA&#xff08;完整状态&#xff09;字段&#xff0c;不过在我试的时候每次PSTAT出现一个它就增加一个&#xff0c;不知道具体是为什么。 最近一直…...

目标检测中的混淆矩阵

一直很疑惑YOLO的这个目标检测 混淆矩阵 🎯 假设任务:检测三种动物(猫、狗、羊) 我们使用一个目标检测模型对图像进行了预测,并收集了如下结果: ✅ 模型预测结果(带类别和框) vs 🟩真实框: 编号真实类别是否被检测到IOU是否合格预测类别备注1猫是✅猫✔️ 正确(…...

前端如何构建跨平台可复用的业务逻辑层(Web、App、小程序)

目录 第一章:跨平台开发的现状与技术选型分析 跨平台技术生态的全景概览 跨平台开发中业务逻辑层的共性需求 不同技术栈对业务逻辑复用的支持程度比较 技术选型中的权衡与思考 第二章:业务逻辑层的核心设计原则与架构理念 设计原则:构建高效业务逻辑层的基础 架构理念…...

day1-小白学习JAVA---JDK安装和环境变量配置(mac版)

JDK安装和环境变量配置 我的电脑系统一、下载JDK1、oracle官网下载适合的JDK安装包&#xff0c;选择Mac OS对应的版本。 二、安装三、配置环境变量1、终端输入/usr/libexec/java_home -V查询所在的路径&#xff0c;复制备用2、输入ls -a3、检查文件目录中是否有.bash_profile文…...

使用VHD虚拟磁盘安装双系统,避免磁盘分区

前言 很多时候&#xff0c;我们对现在的操作系统不满意,就想要自己安装一个双系统 但是安装双系统又涉及到硬盘分区,非常复杂,容易造成数据问题 虚拟机的话有经常用的不爽,这里其实有一个介于虚拟机和双系统之间的解决方法,就是使用虚拟硬盘文件安装系统. 相当于系统在机上…...

数据结构之稀疏矩阵与三元组表示法

稀疏矩阵的概念 在实际应用中&#xff0c;我们经常会遇到一些矩阵&#xff0c;其中大部分元素都是零&#xff0c;只有少量的非零元素。这种矩阵被称为稀疏矩阵。例如&#xff0c;在图像处理、网络分析等领域&#xff0c;稀疏矩阵经常出现。如果使用传统的二维数组来存储稀疏矩…...

微前端框架QianKun

以下是关于 QianKun微前端框架 的系统知识梳理,涵盖核心概念、核心功能、应用间通信、性能优化等内容: 一、QianKun基础概念与核心功能 微前端概念 定义:将单体前端应用拆分为多个独立开发、部署的子应用,通过主应用统一集成。优势:技术栈无关、独立部署、团队自治、增量…...

记录学习的第二十九天

还是力扣每日一题。 本来想着像昨天一样两个循环搞定的&#xff0c;就下面&#x1f447;&#x1f3fb; 不过&#xff0c;结果肯定是超时啦&#xff0c;中等题是吧。 正确答案是上面的。 之后就做了ls题单第一部分&#xff0c;首先是定长滑窗问题 这种题都是有套路的&#xff0…...

C语言复习笔记--字符函数和字符串函数(上)

在编程的过程中&#xff0c;我们经常要处理字符和字符串&#xff0c;为了⽅便操作字符和字符串&#xff0c;C语⾔标准库中提供了 ⼀系列库函数&#xff0c;接下来我们就学习⼀下这些函数。 首先来看下字符函数. 字符分类函数 C语⾔中有⼀系列的函数是专⻔做字符分类的&#xf…...

SQL:聚合函数(Aggregate Functions)

目录 第一性原理出发思考 ——我们为什么需要聚合函数&#xff1f; 什么是聚合函数&#xff1f; 常见聚合函数 实例讲解 &#x1f538; 1. COUNT() —— 计数 &#x1f538; 2. MAX() / MIN() —— 最大 / 最小值 &#x1f538; 3. SUM() —— 求和 &#x1f538; 4. …...

Linux工具学习之【gcc/g++】

&#x1f4d8;前言 书接上文&#xff0c;我们已经学习了 Linux 中的编辑器 vim 的相关使用方法&#xff0c;现在已经能直接在 Linux 中编写C/C代码&#xff0c;有了代码之后就要尝试去编译并运行它&#xff0c;此时就可以学习一下 Linux 中的编译器 gcc/g 了&#xff0c;我们一…...

5.0.2 颜色16进制格式含义 控件template中path的使用

本例要实现的目标如下: 1.右上角的按钮是X的形式(使用path用两根直线绘制) 2.鼠标移动上去以及鼠标点击背景色都变化。(使用不同透明度的白色来区分表示) 一、关于颜色的表示 在C# WPF和WinForms中,Background 属性用于设置控件的背景颜色,可以使用16进制(HEX)格式来表…...

【sharding-jdbc配置以及例子】

一、一个数据库不同的表(分表) &#xff08;1&#xff09;POM <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId…...

OJ笔试强训_1至24天

OJ笔试强训 Day01 [NOIP2010]数字统计_牛客题霸_牛客网 点击消除_牛客题霸_牛客网 两个数组的交集_牛客题霸_牛客网 Day02 牛牛的快递_牛客题霸_牛客网 最小花费爬楼梯_牛客题霸_牛客网 数组中两个字符串的最小距离__牛客网 Day03 简写单词_牛客题霸_牛客网 dd爱框框_…...

多态:面向对象编程的重要特性

摘要&#xff1a;本文全面阐述了面向对象编程中多态这一关键特性&#xff0c;从多态的形式、使用场景、定义及前提条件出发&#xff0c;深入分析其运行特点、弊端&#xff0c;详细介绍引用类型转换相关知识&#xff0c;并通过综合练习强化对多态的理解与应用&#xff0c;为深入…...

使用 Vue 开发登录页面的完整指南

一、项目搭建与基础配置 环境准备 使用 Vue CLI 或 Vite 创建项目&#xff0c;推荐组合&#xff1a;Vue3 Element Plus Vue Router npm create vuelatest npm install element-plus element-plus/icons-vue vue-router 全局配置&#xff08;main.js&#xff09; import { c…...

【Pandas】pandas DataFrame isin

Pandas2.2 DataFrame Indexing, iteration 方法描述DataFrame.head([n])用于返回 DataFrame 的前几行DataFrame.at快速访问和修改 DataFrame 中单个值的方法DataFrame.iat快速访问和修改 DataFrame 中单个值的方法DataFrame.loc用于基于标签&#xff08;行标签和列标签&#…...

Linux 网络接口 /sys/class/net/eth0 文件详解

以下是对 /sys/class/net/eth0 目录下每个文件或目录的详细讲解。这些文件是 Linux 系统中 sysfs 文件系统的一部分&#xff0c;提供了与网络接口&#xff08;这里是 eth0&#xff09;相关的配置和状态信息。每个文件或目录的内容反映了网络接口的特定属性或状态&#xff0c;通…...

java+postgresql+swagger-多表关联insert操作(九)

入参为json&#xff0c;然后根据需要对多张表进行操作&#xff1a; 入参格式&#xff1a; {"username": "车主01","usertel": "11111111111","useridtype": "2","useridcard": null,"proname&qu…...

Jsp技术入门指南【六】jsp脚本原理及隐式对象

Jsp技术入门指南【六】jsp脚本原理及隐式对象 前言一、JSP 脚本元素1.1 声明1.2 表达式1.3 脚本标签 二、JSP 的隐式对象是什么三、隐式对象详解outrequestsessionapplicationconfigexception 前言 在之前的博客中&#xff0c;我们已经介绍了JSP的环境搭建、编译文件查找以及生…...

邮件自动回复助手(Rasa/SMTP)实现教程

在现代办公场景中&#xff0c;处理大量邮件是一项既耗时又容易出错的任务。为了提升工作效率&#xff0c;我们可以利用自然语言处理&#xff08;NLP&#xff09;和邮件传输协议&#xff08;SMTP&#xff09;技术&#xff0c;构建一个智能的邮件自动回复助手。本文将详细介绍如何…...

【vLLM 学习】Aqlm 示例

vLLM 是一款专为大语言模型推理加速而设计的框架&#xff0c;实现了 KV 缓存内存几乎零浪费&#xff0c;解决了内存管理瓶颈问题。 更多 vLLM 中文文档及教程可访问 →https://vllm.hyper.ai/ 源代码&#xff1a;vllm-project/vllm from vllm import LLM, SamplingParams fr…...

《数据结构之美--链表oj练习》

链表oj题分享 1. 移除链表元素 题目&#xff1a; 思路分析&#xff1a; 根据题目描述&#xff0c;可以看出该题是要将满足条件的链表元素删除&#xff0c;并且返回新的头结点. 首先我们想到的肯定是直接遍历该链表然后对满足条件的元素进行删除&#xff0c;但删除某个元素时…...

杂记-LeetCode中部分题思路详解与笔记-HOT100篇-其四

那今天我们就把Hot100的所有题都完结了吧&#xff0c;Hot100作为大多数人笔试题的入门之选&#xff0c;可以说是非常的经典了&#xff0c;但是俗话说得好&#xff0c;书读百遍&#xff0c;其意自现&#xff0c;我不支持反复地只刷部分算法题&#xff0c;但是我支持周期性地刷刷…...

SpringBoot私人西服系统开发与设计

概述 基于SpringBoot的私人西服系统项目&#xff0c;是一个实用的服装管理系统。该系统包含了西服选择、面料选择、预约管理等核心功能。 主要内容 1. 管理员功能模块 用户管理&#xff1a;管理注册用户信息服装款式管理&#xff1a;管理西服款式信息面料类别管理&#xff…...

2.2/Q2,Charls最新文章解读

文章题目&#xff1a;Association of uric acid to high-density lipoprotein cholesterol ratio with the presence or absence of hypertensive kidney function: results from the China Health and Retirement Longitudinal Study (CHARLS) DOI&#xff1a;10.1186/s12882-…...

云端免费训练 AI 大模型推荐(适用于个人学习)

学习 AI 大模型训练&#xff08;如LLM、扩散模型等&#xff09;&#xff0c;云端服务器是必不可少的&#xff0c;因为大模型对算力&#xff08;GPU/TPU&#xff09;和内存要求极高。以下是 适合不同学习阶段 的云端服务器推荐&#xff0c;涵盖 免费、低成本、高性能 选项&#…...

《操作系统真象还原》第九章(2)——线程

《操作系统真象还原》第九章&#xff08;2&#xff09;——线程 文章目录 《操作系统真象还原》第九章&#xff08;2&#xff09;——线程前言多线程调度简单优先级调度的基础任务调度器和任务切换注册时钟中断处理函数实现调度器schedule实现任务切换函数switch_to启用线程调度…...

Windows程序包管理器WinGet实战

概述 WinGet&#xff0c;Windows Package Manager&#xff0c;Windows软件包管理器&#xff0c;开源在GitHub&#xff0c;GitHub Releases可下载&#xff0c;官方文档。 WinGet由一个命令行工具和一组用于在Windows 10/11等版本上安装应用的服务组成&#xff0c;可帮助用户快…...

【特殊场景应对1】视觉设计:信息密度与美学的博弈——让简历在HR视网膜上蹦迪的科学指南

写在最前 作为一个中古程序猿,我有很多自己想做的事情,比如埋头苦干手搓一个低代码数据库设计平台(目前只针对写java的朋友),比如很喜欢帮身边的朋友看看简历,讲讲面试技巧,毕竟工作这么多年,也做到过高管,有很多面人经历,意见还算有用,大家基本都能拿到想要的offe…...

番外篇 | SEAM-YOLO:引入SEAM系列注意力机制,提升遮挡小目标的检测性能

前言:Hello大家好,我是小哥谈。SEAM(Squeeze-and-Excitation Attention Module)系列注意力机制是一种高效的特征增强方法,特别适合处理遮挡和小目标检测问题。该机制通过建模通道间关系来自适应地重新校准通道特征响应。在遮挡小目标检测中的应用优势包括:1)通道注意力增强…...

Top100(26-30)

二叉树的中序遍历 给定一个二叉树的根节点 root &#xff0c;返回 它的 中序 遍历 。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,3,2] 示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[] 示例 3&#xff1a; 输入&#x…...

在 Vue 3 中将拆分后的数组合并回原数组

接上文Vue 3 中按照某个字段将数组分成多个数组_vue3怎么进行数组对象--分割对象-CSDN博客 方法一&#xff1a;使用 flat() 方法 // 假设这是拆分后的多维数组 const splitArrays [[{id: 1, category: A}, {id: 3, category: A}],[{id: 2, category: B}, {id: 5, category: …...

MyBatis如何配置数据库连接并实现交互?

如果你用过MyBatis&#xff0c;肯定知道它的核心功能之一就是数据库连接管理。但很多新手在第一次配置时总会遇到各种问题&#xff1a;数据源怎么配&#xff1f;连接池参数如何调优&#xff1f;XML和注解方式有什么区别&#xff1f;今天我们就来彻底搞懂MyBatis连接数据库的每一…...

PyTorch入门------卷积神经网络

前言 参考&#xff1a;神经网络 — PyTorch Tutorials 2.6.0cu124 文档 - PyTorch 深度学习库 一个典型的神经网络训练过程如下&#xff1a; 定义一个包含可学习参数&#xff08;或权重&#xff09;的神经网络 遍历输入数据集 将输入通过神经网络处理 计算损失&#xff08;即…...

Qt官方案例知识点总结(图形视图——Colliding Mice)

Colliding Mice 案例 图元可重写下面的方法&#xff0c;返回一个QPainterPath(形状)&#xff0c;该形状基于图形项自己的坐标系 返回的形状用于碰撞检测、命中测试等&#xff0c;形状越精确&#xff0c;那么碰撞检测等就越准确 不重写的话&#xff0c;默认取 boundingRect()…...

人工智能在后端开发中的革命:从架构到运维

后端开发作为应用程序的"大脑",正在经历人工智能带来的深刻变革。从智能API设计到自动化数据库优化,从异常预测到资源调度,AI技术正在重塑后端开发的各个方面。本文将全面探讨AI如何赋能现代后端系统开发,并通过实际案例展示这些技术的应用价值。 一、智能API开…...

电子电器架构 --- EOL 工厂刷写(产线)

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 周末洗了一个澡,换了一身衣服,出了门却不知道去哪儿,不知道去找谁,漫无目的走着,大概这就是成年人最深的孤独吧! 旧人不知我近况,新人不知我过…...

AI数据分析与BI可视化结合:解锁企业决策新境界

大家好&#xff0c;今天我们来聊聊一个前沿而热门的话题——AI数据分析与BI可视化结合&#xff0c;如何携手推动企业决策迈向新高度。在数据爆炸的时代&#xff0c;企业如何高效利用这些数据&#xff0c;成为制胜的关键。AI数据分析与BI可视化的结合&#xff0c;正是解锁这一潜…...

深度学习3.2 线性回归的从零开始实现

3.2.1 生成数据集 %matplotlib inline import random import torch from d2l import torch as d2ldef synthetic_data(w, b, num_examples):# 生成特征矩阵X&#xff0c;形状为(num_examples, len(w))&#xff0c;符合标准正态分布X torch.normal(0, 1, (num_examples, len(w…...

ArcPy工具箱制作(下)

在上一篇博客中&#xff0c;我们已经初步了解了如何制作ArcPy工具箱&#xff0c;包括工具箱的基本概念、准备工作、脚本编写以及将脚本转换为工具箱的步骤。今天&#xff0c;我们将继续深入探讨ArcPy工具箱的制作&#xff0c;重点介绍一些进阶技巧和优化方法. 一、优化工具箱的…...

if/switch语句初始化功能

基础介绍 这个特性是在c17版本引入的&#xff0c;在这之前是不允许在if语句或者switch语句中使用赋值语句&#xff0c;不仅仅是if语句和switch语句&#xff0c;包括lambda表达式在c17版本也支持类在捕获表达式中支持赋值操作。言归正传&#xff0c;下面阐述这个特性的基本语法…...

cmake 语法大纲

1&#xff0c;基础语法 CMakeLists.txt 目录组织文件&#xff1b; *.cmake 脚本文件 运行: $ cmake -P xxx.cmake *.cmake 模块文件 include 命令来引用 模块文件。 自定义模块&#xff1b; cmake 预制模块&#xff1b; 单行注释 # com 括号注释 #…...