C++初阶 - 5.C/C++内存管理
目录
1.C/C++的内存分布
2.C语言中动态内存管理方式:malloc、calloc、realloc、free
3.C++内存管理方式
3.1 new/delete操作内置类型
3.2 new 和 delete操作自定义类型
4.operator new 与 operator delete 函数(重要点)
4.1 operator new 与 operator delete函数(重点)
4.2 重载 operator new 与operator delete(了解)
5.new 和 delete 的实现原理
5.1 内置类型
5.2 自定义类型
6. 定位 new 表达式(placement-new)(了解)
7.常见面试题
7.1 malloc / free 和 new / delete 的区别
7.2 内存泄漏
7.2.1什么式内存泄漏,内存泄漏的危害
7.2.2 内存泄漏的危害
7.2.3 如何检测内存泄漏(了解)
7.2.4 如何避免内存泄漏
1.C/C++的内存分布
我们先来看一下下面的代码和相关问题
int globalVar = 1;
static int staticGlobalVar = 1;
void Test()
{static int staticVar = 1;int localVar = 1;int num1[10] = { 1, 2, 3, 4 };char char2[] = "abcd";const char* pChar3 = "abcd";int* ptr1 = (int*)malloc(sizeof(int) * 4);int* ptr2 = (int*)calloc(4, sizeof(int));int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);free(ptr1);free(ptr3);
}1. 选择题:
选项: A.栈 B.堆 C.数据段(静态区) D.代码段(常量区)
globalVar在哪里?__C__ // 全局变量,全局变量和静态数据存放在 数据段(静态区)
staticGlobalVar在哪里?__C__ // 静态数据,全局变量和静态数据段存放在 数据段(静态区)
staticVar在哪里?__C__ // 静态数据,全局变量和静态数据段存放在 数据段(静态区)
localVar在哪里?__A__ //局部变量, 局部变量和函数存放在栈
num1 在哪里?__A__ //局部变量, 局部变量和函数存放在栈
char2在哪里?__A__ //局部变量, 局部变量和函数存放在栈
*char2在哪里?__A_ //局部变量, 局部变量和函数存放在栈
pChar3在哪里?__A__ //pChar3是一个指针变量,存储'abcd'的地址,属于局部变量, 局部变量和函数存放在栈
*pChar3在哪里?__D__ //pChar3是一个指针变量,存储'abcd'的地址,解引用后找到'abcd','abcd\0'存储在常量区。
ptr1在哪里?__A__ //ptr1是一个指针变量,存储malloc的地址,属于局部变量, 局部变量和函数存放在栈
*ptr1在哪里?__B__ //ptr1是一个指针变量,存储malloc的地址,解引用后拿到malloc的内容,该内容存放在堆区。2. 填空题:
sizeof(num1) = __40__; //sizeof(数组名),求该数组的大小,4 * 10 = 40
sizeof(char2) = __5__; //sizeof(数组名),求该数组的大小,"abcd" = "abcd\0" 一共5个元素,1 * 5 = 5
strlen(char2) = __4__; //strlen()是库函数,求字符串长度,"abcd"一共4个元素。
sizeof(pChar3) = _4/8___;//pChar3是一个指针变量,指针变量的大小受操作系统影响,4/8
strlen(pChar3) = __4__; //strlen()是库函数,求字符串长度,"abcd"一共4个元素。
sizeof(ptr1) = __4/8__; //ptr1是一个指针变量,指针变量的大小受操作系统影响,4/83. sizeof 和 strlen 区别?
sizeof()是操作符,求取变量的大小,
strlen()是函数,求的是字符串的长度,需要注意字符串一般末尾有'\0'作为结束标识符。

【说明】
- 栈又叫堆栈--非静态局部变量/函数参数/返回值等等,栈是向下增长的。
- 内存映射段--高效的IO映射方式,用于装载一个共享的动态内存库,用户可使用系统接口创建共享内存,做进程间通信,(Linux部分会详细讲解)
- 堆--用于程序运行时动态内存分配,堆是向上增长。
- 数据段--存储全局变量和静态数据。
- 代码段--可执行的代码/只读常量。
2.C语言中动态内存管理方式:malloc、calloc、realloc、free
void Test ()
{int* p1 = (int*) malloc(sizeof(int));free(p1);// 1.malloc/calloc/realloc的区别是什么?int* p2 = (int*)calloc(4, sizeof (int));int* p3 = (int*)realloc(p2, sizeof(int)*10);// 这里需要free(p2)吗?/*不需要,realloc扩容方式分为两种:原地扩容,地址不改变。新位置扩容,copy原位置的内容,给到新位置,返回新位置的地址。*/free(p3 );
}
面试题:
1.malloc/calloc/realloc的区别?
malloc申请的空间没有初始化,直接返回起始地址。
calloc申请的空间,会把空间初始化为0,然后返回起始地址。
realloc是对已经开辟好的空间进行扩容,扩容方式分为两种:
原地扩容,地址不改变。
新位置扩容,copy原位置的内容,给到新位置,返回新位置的地址。
2.malloc的实现原理?
【CTF】GLibc堆利用入门-机制介绍_哔哩哔哩_bilibili
3.C++内存管理方式
C语言内存管理方式在C++中可以继续使用,但是有些地方就无能为力,而且使用起来比较麻烦,因此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。
3.1 new/delete操作内置类型
#include<iostream>
using namespace std;
int main()
{//动态申请一个int类型的空间//C int* p1 = (int*)malloc(sizeof(int));free(p1);//CPPint* p2 = new int;delete p2;//动态申请10个int类型的空间//Cint* p3 = (int*)malloc(sizeof(int) * 10);free(p3);//CPPint* p4 = new int[10];delete[] p4;//动态申请一个int类型的空间并初始化为10//CPPint* p5 = new int(10);cout << "p5;" << *p5 << endl;delete p5;//动态申请一个int类型的数组空间并初始化为{1,2,3,0}//CPPint* p6 = new int[10] {1,2,3,0};for (int i = 0; i < 10; i++){cout << "p6;" << *(p6+i) << endl;}delete[] p6;return 0;
}


注意:申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用new[] 和 delete[]。注意:匹配起来使用。
3.2 new 和 delete操作自定义类型
class A
{
public:A(int a = 0):_a(a){cout << "A()" << this << endl;}~A(){cout << "~A()" << this << endl;}
private:int _a;
};int main()
{//new / delete 和 malloc / free最大的区别是 new /delete 对于【自定义类型还】除了开辟空间还会调用构造函数和析构函数A* p1 = (A*)malloc(sizeof(A));A* p2 = new A(1);free(p1);delete p2;//内置类型几乎是一样的int* p3 = (int*)malloc(sizeof(int));//Cint* p4 = new int;free(p3);delete p4;A* p5 = (A*)malloc(sizeof(A)*10);A* p6 = new A[10];free(p5);delete[] p6;return 0;
}
注意:在申请自定义类型的空间时,new会调用构造函数,delete 会调用析构函数,而malloc和free不会。
【面试题】
1.C语言malloc\free 与C++new、delete 的区别?
动态申请内置类型的数据:new / malloc 除了用法上面,其他没有什么区别。
动态申请自定义类型的数据:new / malloc 除了用法上面,new会调用构造函数初始化,delete会调用析构函数清理。
4.operator new 与 operator delete 函数(重要点)
4.1 operator new 与 operator delete函数(重点)
new 和 delete 是用户进行动态内存申请和释放的操作符,operator new 和 operator delete 是系统提供的全局函数,new在底层调用了operator new 全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间。
/*
operator new:该函数实际通过malloc来申请空间,当malloc申请空间成功时直接返回;申请空间
失败,尝试执行空 间不足应对措施,如果改应对措施用户设置了,则继续申请,否
则抛异常。
*/
void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
{// try to allocate size bytesvoid *p;while ((p = malloc(size)) == 0)if (_callnewh(size) == 0){// report no memory// 如果申请内存失败了,这里会抛出bad_alloc 类型异常static const std::bad_alloc nomem;_RAISE(nomem);}return (p);
}/*
operator delete: 该函数最终是通过free来释放空间的
*/
void operator delete(void *pUserData)
{_CrtMemBlockHeader * pHead;RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));if (pUserData == NULL)return;_mlock(_HEAP_LOCK); /* block other threads */__TRY/* get a pointer to memory block header */pHead = pHdr(pUserData);/* verify block type */_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));_free_dbg( pUserData, pHead->nBlockUse );//------------------------------__FINALLY_munlock(_HEAP_LOCK); /* release other threads */__END_TRY_FINALLYreturn;
}/*
free的实现
*/
#define free(p) _free_dbg(p, _NORMAL_BLOCK)//-----------------------------
通过上述两个全局变量的实现,operator new 实际也是通过malloc来申请空间的,如果malloc申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施就继续申请,否则就抛异常。operator delete 最终是通过free来释放空间的。
4.2 重载 operator new 与operator delete(了解)
注意:一般情况下不需要对operator new 和 operator delete进行重载,除非在申请和释放空间的时候有某些特殊的需求。比如:在使用new和delete申请空间和释放空间时,打印一些日志信息,可以帮助用户来检测时候存在内存泄漏。
// 重载operator delete,在申请空间时:打印在哪个文件、哪个函数、第多少行,申请了多少个
字节
void* operator new(size_t size, const char* fileName, const char* funcName,
size_t lineNo)
{void* p = ::operator new(size);cout << fileName << "-" << funcName << "-" << lineNo << "-" << p << "-"<< size << endl;return p;
}
// 重载operator delete,在释放空间时:打印再那个文件、哪个函数、第多少行释放
void operator delete(void* p, const char* fileName, const char* funcName,
size_t lineNo)
{cout << fileName << "-" << funcName << "-" << lineNo << "-" << p <<endl;::operator delete(p);
}
int main()
{// 对重载的operator new 和 operator delete进行调用int* p = new(__FILE__, __FUNCTION__, __LINE__) int;operator delete(p, __FILE__, __FUNCTION__, __LINE__);return 0;
}
// 上述调用显然太麻烦了,可以使用宏对调用进行简化
// 只有在Debug方式下,才调用用户重载的 operator new 和 operator delete
#ifdef _DEBUG
#define new new(__FILE__, __FUNCTION__, __LINE__)
#define delete(p) operator delete(p, __FILE__, __FUNCTION__, __LINE__)
#endif
int main()
{int* p = new int;delete(p);return 0;
}
5.new 和 delete 的实现原理
5.1 内置类型
如果申请的是内置类型的空间,new 和 malloc,delete 和free 基本相似,不同的地方是:new / delete 申请和释放的是首个元素的空间,new[] 和 delete[] 申请的是连续空间,而且new在申请空间失败时会抛异常,malloc会返回NULL;
5.2 自定义类型
- new的原理
- 调用operator new 函数申请空间
- 在申请的空间上执行构造函数,完成对象的构造
- delete 的原理
- 在空间上执行析构函数,完成对象中资源的清理工作
- 调用operator delete 函数释放对象的空间
- new T[N]的原理
- 调用operator new[] 函数,在operator new[] 中实际调用operator new 函数完成对N 个对象空间的申请
- 在盛情的空间上执行N次构造函数
- delete[] 的原理
- 在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理
- 调用operator delete[] 释放空间。实际在operator delete[] 中调用 operator delete 来释放空间。
6. 定位 new 表达式(placement-new)(了解)
定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象。
使用格式:
new(place_address)type 或者 new(place_address)type(initializer-list)
place_address 必须是一个指针,initializer-list是类型的初始化列表
使用场景:
定位 new 表达式在实际中一般是配和内存池使用,因为内存池分配出的内存没有初始化,所以如果是自定义类型的对象,需要使用new的定义表达式进行显示调用构造函数进行初始化。
class A
{
public:A(int a = 0): _a(a){cout << "A():" << this << endl;}
~A(){cout << "~A():" << this << endl;}
private:int _a;
};
// 定位new/replacement new
int main()
{// p1现在指向的只不过是与A对象相同大小的一段空间,还不能算是一个对象,因为构造函数没有执行A* p1 = (A*)malloc(sizeof(A));new(p1)A; // 注意:如果A类的构造函数有参数时,此处需要传参p1->~A();free(p1);A* p2 = (A*)operator new(sizeof(A));new(p2)A(10);p2->~A();operator delete(p2);return 0;
}
7.常见面试题
7.1 malloc / free 和 new / delete 的区别

7.2 内存泄漏
7.2.1什么式内存泄漏,内存泄漏的危害
什么式内存泄偶?
内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况,内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计失误,失去了对该段内存的控制,因而造成了内存的浪费。
内存泄漏的危害?
长期运行的程序出现内存泄漏影响很大,如操作系统,后台服务等等,出现内存泄漏会导致响应越来越慢,最终卡死。
void MemoryLeaks()
{// 1.内存申请了忘记释放int* p1 = (int*)malloc(sizeof(int));int* p2 = new int;// 2.异常安全问题int* p3 = new int[10];Func(); // 这里Func函数抛异常导致 delete[] p3未执行,p3没被释放.delete[] p3;
}
7.2.2 内存泄漏的危害
C/C++程序中一般我们关心两种方面的内存泄漏:
堆内存泄漏:
堆内存指的是程序执行中依据要分配通过malloc / calloc / realloc / new 等从堆中分配的一块内存,用完后必须通过调用相应的 free 或者 delete 删掉。假设程序的设计错误导致这部分内存没有被释放,那么以后这部分空间将无法被使用,就会产生Heap Leak。
系统资源泄漏
指程序使用系统分配的资源,比如套接字、文件描述符、管道等没有使用对应的函数释放掉,导致系统资源的浪费,严重可导致系统效能减少,系统执行不稳定。
7.2.3 如何检测内存泄漏(了解)
在vs下可以使用windows操作系统提供的 _CrtDumpMemoryLeaks() 函数进行简单检测,该函数只报出了大概泄漏了多少个字节,没有其他更准确的位置信息。
int main()
{int* p = new int[10];// 将该函数放在main函数之后,每次程序退出的时候就会检测是否存在内存泄漏_CrtDumpMemoryLeaks();return 0;
}// 程序退出后,在输出窗口中可以检测到泄漏了多少字节,但是没有具体的位置
Detected memory leaks!
Dumping objects ->
{79} normal block at 0x00EC5FB8, 40 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.
因此写代码时一定要小心,尤其是动态内存操作时,一定要记着释放。但有些情况下总是防不胜防,简单的可以采用上述方式快速定位下。如果工程比较大,内存泄漏位置比较多,不太好查时一般都是借助第三方内存泄漏检测工具处理的。
- 在linux下内存泄漏检测:Linux下几款C++程序中的内存泄露检查工具
- 在windows下使用第三方工具:VS编程内存泄漏
- 其他工具:https://www.cnblogs.com/liangxiaofeng/p/4318499.html
7.2.4 如何避免内存泄漏
- 工程前期良好的设计规范,养成良好的编码规范,申请的内存空间记者匹配去释放。ps:
这个理想状态。但是如果碰上异常时,就算注意释放了,还是可能会出问题。需要下一条智
能指针来管理才有保证。 - 采用RAII思想或者智能指针来管理资源。
- 有些公司内部规范使用内部实现的私有内存管理库。这套库自带内存泄漏检测的功能选项。
- 出问题了使用内存泄漏工具检测。ps:不过很多工具都不够靠谱,或者收费昂贵。
总结一下:内存泄漏非常常见,解决方案分为两种:
1、事前预防型。如智能指针等。
2、事后查错型。如泄漏检测工具。
相关文章:
C++初阶 - 5.C/C++内存管理
目录 1.C/C的内存分布 2.C语言中动态内存管理方式:malloc、calloc、realloc、free 3.C内存管理方式 3.1 new/delete操作内置类型 3.2 new 和 delete操作自定义类型 4.operator new 与 operator delete 函数(重要点) 4.1 operator new 与…...
数学建模学习(3):综合评价类问题整体解析及分析步骤
一、评价类算法的简介 对物体进行评价,用具体的分值评价它们的优劣 选这两人其中之一当男朋友,你会选谁? 不同维度的权重会产生不同的结果 所以找到每个维度的权重是最核心的问题 0.25 二、评价前的数据处理 供应商ID 可靠性 指标2 指…...
【后端面经】微服务构架 (1-5) | 限流:濒临奔溃?限流守护者拯救系统于水火之中!
文章目录 一、前置知识1、什么是限流?2、限流算法A) 静态算法a) 漏桶b) 令牌桶c) 固定窗口d) 滑动窗口B) 动态算法3、限流的模式4、 限流对象4、限流后应该怎么做?二、面试环节1、面试准备2、基本思路3、亮点展现A) 突发流量(针对请求个数而言)B) 请求大小(针对请求大小而言)…...
HDFS异构存储详解
异构存储 HDFS异构存储类型什么是异构存储异构存储类型如何让HDFS知道集群中的数据存储目录是那种类型存储介质 块存储选择策略选择策略说明选择策略的命令 案例:冷热温数据异构存储对应步骤 HDFS内存存储策略支持-- LAZY PERSIST介绍执行使用 HDFS异构存储类型 冷…...
《面试1v1》Kafka消息是采用Pull还是Push模式
🍅 作者简介:王哥,CSDN2022博客总榜Top100🏆、博客专家💪 🍅 技术交流:定期更新Java硬核干货,不定期送书活动 🍅 王哥多年工作总结:Java学习路线总结…...
Windows环境Docker安装
目录 安装Docker Desktop的步骤 Docker Desktop 更新WSL WSL 的手动安装步骤 Windows PowerShell 拉取(Pull)镜像 查看已下载的镜像 输出"Hello Docker!" Docker Desktop是Docker官方提供的用于Windows的图形化桌面应用程序,…...
Spring 6.0官方文档示例(23): singleton类型的bean和prototype类型的bean协同工作的方法(二)
使用lookup-method: 一、实体类: package cn.edu.tju.domain2;import java.time.LocalDateTime; import java.util.Map;public class Command {private Map<String, Object> state;public Map<String, Object> getState() {return state;}public void …...
Docker Compose 容器编排
Docker compose Docker compose 实现单机容器集群编排管理(使用一个模板文件定义多个应用容器的启动参数和依赖关系,并使用docker compose来根据这个模板文件的配置来启动容器) 通俗来说就是把之前的多条docker run启动容器命令 转换为docker…...
while循环
while循环是一种常见的循环结构,它会重复执行一段代码,直到指定的条件不再满足。 基本语法如下: while 条件: # 循环体代码 其中,条件是一个布尔表达式,如果为True,则执行循环体中的代码;如果…...
从JVM指令看String对象的比较
在翻看各类 java 知识中,总会提到如下知识:比较 String 对象,例如: String a1new String("10"); String a2"10"; String a3"1""0";//结果 System.out.println(a1a2); //false System.ou…...
python与深度学习(六):CNN和手写数字识别二
目录 1. 说明2. 手写数字识别的CNN模型测试2.1 导入相关库2.2 加载数据和模型2.3 设置保存图片的路径2.4 加载图片2.5 图片预处理2.6 对图片进行预测2.7 显示图片 3. 完整代码和显示结果4. 多张图片进行测试的完整代码以及结果 1. 说明 本篇文章是对上篇文章训练的模型进行测试…...
Linux使用教程
一、Linux命令基础 1、ls、ll命令——展示数据 ①ls命令——平铺展示数据 其中ls命令以平铺的方式展现数据 ②ll命令——列表展示数据 ll命令以列表的方式展现数据 -a选项,表示:all的意思,即列出全部文件(包含隐藏的文件/文件夹…...
项目名称:智能家居边缘网关项目
一,项目介绍 软件环境: C语言 硬件环境: STM32G030C8TX单片机开发板 开发工具: Linux平台GCC交叉编译环境以及ukeil (1)边缘网关概念 边缘网关是部署在网络边缘侧的网关,通过网络联接、协议转换等功能联接物理和数字世界,提供轻量化的联接管…...
SciencePub学术 | 物联网类重点SCIEEI征稿中
SciencePub学术 刊源推荐: 物联网类重点SCIE&EI征稿中!信息如下,录满为止: 一、期刊概况: 物联网类重点SCIE&EI 【期刊简介】IF:7.5-8.0,JCR1区,中科院1/2区TOP; 【出版社…...
EtherNet/IP转Modbus网关以连接AB PLC
本案例为西门子S7-1200 PLC通过捷米特Modbus转EtherNet/IP网关捷米特JM-EIP-RTU连接AB PLC的配置案例。 网关分别从ETHERNET/IP一侧和MODBUS一侧读写数据,存入各自的缓冲区,网关内部将缓冲区的数据进行交换,从而实现两边数据的传输。 网关做为…...
mysql用户添加
一、连接mysql服务 mysql -u root -p 二、查询用户表 use mysql ; SELECT User, Host FROM mysql.user; 三、新增用户并授权 Create USER dev4rw% IDENTIFIED WITH mysql_native_password BY 新密码; GRANT ALL PRIVILEGES ON *.* TO dev4rw% WITH GRANT OP…...
628. 三个数的最大乘积
628. 三个数的最大乘积 class Solution {public int maximumProduct(int[] nums) {Arrays.sort(nums); return Math.max(nums[nums.length-1]*nums[nums.length-2]*nums[nums.length-3],nums[0]*nums[1]*nums[nums.length-1]);} }...
linux驱动开发入门(学习记录)
2023.7.6及7.7 概述了解 一 1.驱动框架 2. 字符设备 块设备,存储相关 网络设备驱动 不一定属于某一种类型二 1.获取外设或传感器数据,控制外设,数据会提交给应用程序 2.编写一个驱动,及测试应用程序 app。驱动和应用完全分开 3.驱…...
SpringCloud-Alibaba之Sentinel熔断与限流
一、下载安装运行 http://localhost:8080进行访问 登录账号和密码均为sentinel 二、创建工程,并注册到nacos服务中心 依赖spring-cloud-starter-alibaba-nacos-discovery,spring-cloud-starter-alibaba-sentinel sentine-datasource-nacos (持久化)配置文件 se…...
深“扒”云原生高性能分布式文件系统JuiceFS
JuiceFS 是一款面向云原生设计的高性能分布式文件系统,在 Apache 2.0 开源协议下发布。提供完备的 POSIX 兼容性,可将几乎所有对象存储接入本地作为海量本地磁盘使用,亦可同时在跨平台、跨地区的不同主机上挂载读写。 JuiceFS 简介 JuiceFS…...
业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...
R 语言科研绘图第 55 期 --- 网络图-聚类
在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…...
git: early EOF
macOS报错: Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...
鸿蒙(HarmonyOS5)实现跳一跳小游戏
下面我将介绍如何使用鸿蒙的ArkUI框架,实现一个简单的跳一跳小游戏。 1. 项目结构 src/main/ets/ ├── MainAbility │ ├── pages │ │ ├── Index.ets // 主页面 │ │ └── GamePage.ets // 游戏页面 │ └── model │ …...
客户案例 | 短视频点播企业海外视频加速与成本优化:MediaPackage+Cloudfront 技术重构实践
01技术背景与业务挑战 某短视频点播企业深耕国内用户市场,但其后台应用系统部署于东南亚印尼 IDC 机房。 随着业务规模扩大,传统架构已较难满足当前企业发展的需求,企业面临着三重挑战: ① 业务:国内用户访问海外服…...
