- 博客(47)
- 收藏
- 关注
原创 段错误,如何调试
Ubuntu下找不到核心转储文件(core dump)的解决方案 - 知乎Ubuntu20.04出现段错误核心已转储问题解决方案_段错误 (核心已转储)-CSDN博客
2025-04-21 17:29:33
320
原创 小车正常但是加载不出地图 找不到mapserver
小车正常但是加载不出地图 找不到mapserverRequest for map failed; trying again...找不到mapserver
2025-04-17 21:27:22
160
原创 proto安装、编译、多版本以及编译找不到链接库
记录个小问题,protoc版本问题:之前装过3.14,但是莫名其妙今天运行成3.6.1了,需要删除这个版本重新安装,更换版本同样操作。在学习grpc时,需要使用3.19版本,将新版本放入不同的文件位置。(可以看到这个位置不对,不是我当初安装的位置了)以c++为例,下载最新的发布版。不要重复的make,万一重复了。下载源码 发布版地址。
2025-03-31 21:26:18
481
原创 红黑树、B树、B+树基本原理
叶节点包含了B+树的所有元素,是一个链表(单向双向都有),每个元素的值就是表格的关键字key。LL自身右旋,RR自身左旋,LR(左右)孩子左旋,自身右旋,RL(右左)孩子右旋,自身左旋。前面B树的查找是随机查找,遍历树的时候是中序遍历,效率比较低,B+树解决了这个问题。同时继续观察:L右旋,R左旋,LR和RL先旋转失衡的孩子,再旋转失衡的自身。有序:节点内的数据是有序的,任意元素的左子树都小于他,右子树都大于他。节点内的查找是在内存中进行的,一般是顺序查找或者二分查找,效率差不多。
2025-03-18 15:29:57
634
原创 protubuf序列化和反序列化原理
编码方法:把一个整数的二进制,每次取七位,最高位作为标志位,1表示后续字节还是当前数据的,0表示这是当前数据的最后一个数据,按照小端存储。通过映射表看非常简单:从零开始,然后负数正数交替,正数被扩大了两倍,中间的空隙正好存负数。参考上面的例子,原本四个字节的32位int数据就只占用了三个字节,节省了一个字节。:为了解决varint编码处理负数效率低的问题,实现原理:位移映射。也很好记 zigzag 之字形的,z是之字形的,映射表也是之字形的。倒序,前面加表示为,未结束就是1,结束了就是0;
2025-03-17 19:08:19
439
原创 c++11新特性之线程异步
future类是用来异步存储数据的promise 类对象要作为子线程任务函数的参数传入子线程,可以在任务函数中任意位置通过set_value返回值packaged_task类通过包装任务函数,通过std::ref将自身对象的引用作为任务函数传给子线程,通过任务函数返回值返回数据async不需要创建子线程,直接穿任务函数,通过设置执行策略,来选择创建子线程立即执行还是在主线程执行(不会创建子线程)
2025-03-04 15:14:06
627
原创 c++11新特性之条件变量
这个可以使用的锁很多,包括递归互斥锁,超时互斥锁,超时递归互斥锁,以及lock_guard。条件变量:放心n个线程,阻塞N个线程,主要使用场景:生产者-消费者模型。只能使用独占的互斥锁,并且还得配合unique_lock。互斥锁:放行一个线程,阻塞N个线程。
2025-03-03 23:22:35
374
原创 using的c++11新特性
和typedef一样,using 也可以用来起别名using 新类型 = 原类型区别体现在定义函数指针这里typedef其实是函数别名,本质是一个函数指针,也就是指针,他的返回值是int,参数列表是。
2025-03-03 23:19:52
122
原创 c++11新特性之可调用对象绑定器和包装器
发现了没,以上情况都获得了一种统一的使用格式,除了:类的非静态成员函数和对象,这就要使用绑定器bind了。operator前面不能写返回值类型,但是要return,return的内容是想要转换的类型。operator类型转换操作符是将类对象转化为其他数据类型。上面展示了可调用对象的使用,其实是比较麻烦并且多样的,operator后面跟(),并且参数列表必须为空。可以是一个指针(普通函数的函数名,函数指针)简单用法此前整理过,只介绍与此相关的用法。转换后的对象可以当做函数名来使用。绑定类的成员函数或变量。
2025-03-03 23:19:16
1133
原创 c++11新特性之原子变量atomic
那就有一个可能,在操作数据完了以后,还没来得及写入内存,就失去了cpu时间片,那时候数据会在cpu中进行缓存,处理下一个数据,那如果下一个操作也是对这个数据做修改,他读到的还是修改之前的数据,就会产生问题。就不写例子了,假如多个线程操作一个共享资源 int count ,做加一操作,各自循环一百次,结果应该是200,但是由于没有做线程安全,结果可能是199。注意一个问题:前面说atomic不能操作复合类型,虽然可以使用一个类指针,但是原子操作保护的是这个指针的操作是原子的,而不是他指向的内存也是安全的。
2025-03-03 23:18:24
447
原创 3-3内存映射区
addr 从动态库的什么位置开始创建内存映射区,一般指定为NULL,委托内核分配。fd:文件描述符,映射区通过这个文件描述符和磁盘文件建立联系。offset:磁盘文件偏移量,文件从偏移到的位置开始映射。length 大小(字节)
2025-03-03 23:05:45
254
原创 3-2管道
有名管道在磁盘上有实体,文件类型为p,文件大小永远为0,因为他将数据存储在内核缓冲区,打开管道文件就得到操作有名管道的文件描述符。的一种方式,本质是内核区的一块内存,内核缓冲区,其中的数据存储在一个环形队列中,匿名管道只能在有血缘关系的进程间通信(父子,兄弟)有名管道可以在进程间通信,和血缘关系无关。- mode:文件操作权限。
2025-03-03 23:05:14
141
原创 3-4共享内存
当进程不需要操作共享内存了,解除关联,如果不解除,进程退出的时候也会自动解除。打开和创建共享内存以后还必须和共享内存关联,这样才能得到共享内存的起始地址。shmget需要自己设置key指,ftok函数可以自动生成,返回key。调用删除函数以后不会立刻删除,只有所有关联的进程都解除关联才会删除。proj_id:当作字符处理,取值范围1-255。如果不存在需要创建共享内存。
2025-03-03 23:04:13
400
原创 c++线程同步--互斥锁
c++提供了四种互斥锁std::mutex:独占互斥锁std::timed_mutex:超时独占互斥锁,不能递归std::recursive_mutex:递归互斥锁,不带超时std::recursive_timed_mutex:带超时的递归互斥锁。
2025-03-03 23:03:30
957
原创 3-1进程控制
两个进程的数据并不能互用,前面说到父子进程是独立的虚拟地址空间,父进程做数据更新不会影响子进程,同样子进程更改数据也不会影响父进程,全局变量也无法实现这一点,因为存储全局变量的区(.bss .data)也进行了拷贝。exec族没有创建进程的能力,他是将自己的空间里的用户区清空,只保留一些进程id之类的信息,让新进程寄生在自己的空间里。arg:指定进程的名字,一般和要启动的可执行程序同名,可以通过ps aux查看。磁盘上的应用程序启动会得到一个进程,在这个进程中创建进程,称之为子进程,
2025-02-28 22:13:18
892
原创 2-2linux系统IO
假设在创建新文件的时候, 给 open 指定第三个参数指定新文件的操作权限, 文件也是会被创建出来的, 只不过新的文件的权限可能会有点奇怪,实际使用的时候,当出现错误的时候会有对应的返回值,我们只知道返回值,至于它的错误是什么,可以调用perror自动输出,还可以添加提示信息s。这里纠结了很久,想直接去看c++的文件io,但是没有必要,文件操作的open/close用c标准就行了,所以回过头来看了。系统函数是系统专有的函数,不是内核函数,内核函数是不允许用户使用的,所以系统函数来做这个桥梁调用它。
2025-02-28 22:11:40
478
原创 2-1文件描述符
进程在运行过程中,程序内部的指令都是通过cpu完成的,cpu只进行数据运算,不具备数据存储能力,其处理的数据从物理内存中加载进到,到写入物理内存,都是依靠内存管理单元MMU实现的。如果是虚拟地址,虚拟地址分配到0 - 100,其他程序也分配0 - 100,进程不知道这里的0-100映射到物理地址是多少。在linux中,一切都被抽象成了文件,,需要一个文件描述符来操作这些文件,同时,所有的文件描述符都维护。首先明白一个规则,物理内存的使用是连续的,同样的进程占用内存也是连续的。物理内存的使用是经常变化的,
2025-02-28 22:10:55
745
原创 1-6静态库和动态库
因为示例代码中,源代码包含了这个头文件,并且在头文件中声明了所有将要定义的函数,那么在打完成静态库之后,这个头文件就成为了记录静态库功能的 函数名单。B公司愿意给A使用,但是不想给他源代码,所以提供一些接口给A用,调用的时候就调用指定的函数名,并不知道具体实现。A公司想要使用B公司的源文件,直接加进来项目会变得庞大,所以把B包装成一个库。即使gcc指定了-L 的搜索路径,动态链接器并不知道,他有自己的搜索顺序。路径之间使用:间隔,使用$解出原来的内容在追加。两者的优缺点从两个出发点考虑。
2025-02-28 22:08:24
367
原创 1-5gcc
在程序中有很多打印输出,这些在程序完成后是不需要的,如果事后删除很麻烦,就可以在程序里使用。在调试的时候,编译指定宏,调试完成不在指定,自动就会删除。g++可以直接编译cpp,而gcc需要指定链接参数。2.1 指定一个宏(-D)两者都既可以编译C/C++
2025-02-28 22:07:43
371
原创 1-4查找命令
根据文件的属性来查找文件:例如根据 文件名、文件类型、文件大小、文件目录深度等。和-exec的使用完全一样,但是在执行命令的时候会询问 y?使用这个不需要后面加{};
2025-02-28 22:06:13
286
原创 linux(1)文件管理
lost+found:一般是空的,非正常关机和系统崩溃会存储临时文件,用来恢复的目录。dev:设备目录,所有的硬件都会抽象成文件存储,比如鼠标键盘。var:存储了系统使用的一些经常发生变化的目录,比如日志文件。media:和dev完全相同,可以选择用来挂载一些长期的设备。head -行数 filename 前多少行。proc:内存使用的一个映射目录,给系统使用的。tmp:临时目录,存放临时数据,重启电脑会删除。tail -行数 filename 后多少行。mnt:临时挂载点目录,比如临时U盘。
2025-02-28 22:03:05
656
原创 c++11新特性 chrono库
算术运算符(非成员函数) operator+ tp + dtn a time_point value。算术运算符(非成员函数) operator- tp - dtn a time_point value。关系操作符(非成员函数) operator== tp == tp2 a bool value。关系操作符(非成员函数) operator>= tp >= tp2 a bool value。关系操作符(非成员函数) operator<= tp <= tp2 a bool value。
2025-02-28 21:59:31
1084
原创 C++11新特性 thread线程类
如果不加这个函数,主线程执行完就退出了,释放了虚拟地址空间,但是子线程还没执行完,有的线程可能都没有机会执行。获取cpu核心数,如果让每个线程独自占有一个cpu的核,那么他们之间是并行的,效率是最高的。每个进程都占用一个虚拟地址空间,但是进程中不管创建多少线程都共用一个地址空间。移动是允许的,拷贝是不允许的,资源是不能复制的。,直到调用它的子线程执行完,主线程才解除阻塞。父子进程是否是关联的。
2025-02-28 21:57:47
407
原创 day6 哈希 字母异位词、集合交集、快乐数、两数之和
当我们遇到要快速判断元素是否出现在集合里时,优先使用哈希法牺牲空间换时间242. 有效的字母异位词 - 力扣(LeetCode)用哈希,把字母的相对位置作为key,出现次数作为value,public:i < 26;
2023-10-24 14:02:30
117
原创 day5 链表相交、环形链表
现在,slow到达入口时,fast必然已经在环内,fast slow距离为k,一圈的长度为n,(k + n)/ 2 < n,说明 slow并未绕完一周,就已经相遇。定义快指针每步走两次,慢指针每步一次,如果有环,必然会相遇,得到一个相遇点,从相遇点到入口的长度 等于 从head到入口的长度(数学推导),fast步长为2,slow步长为1 , fast相对于slow步长为1,fast一步一步逼近slow,不会跳过去。,无论是第几圈相遇,不同的是经过的圈数 k ( y + z)快指针索引到链表的结尾。
2023-10-22 22:10:46
129
1
原创 代码随想录训练营day3|203. 移除链表元素、707. 设计链表、206. 反转链表
/单链表int val;203. 移除链表元素 - 力扣(LeetCode)一、不设置虚拟头指针 AC在得到一个链表之后,通过定义一个链表类型的指针指向该链表的头指针,来进行操作链表指针的赋值实际上是重新定义指针的指向需要临时指针来命名需要删除的指针,它本身没有命名,他的名字由上一个链表元素的next定位,当next需要改变指向时,将没有指针指向这块内存,届时将无法释放它。else {二、虚拟头指针。
2023-10-15 14:53:59
435
1
原创 代码随想录训练营第2天|977.有序数组的平方、209.长度最小的子数组、59.螺旋数组Ⅱ
数组是存放在连续内存空间上的相同数据类型的集合数组元素不能删除,只能覆盖(内存空间连续).vector的底层是array。
2023-10-13 20:31:02
98
原创 代码随想录训练营第一天|704.二分查找、27.移除元素
慢指针:更新新数组的下标(只要不等于val,就更新数组下标,等于val时,slowIndex等待fastIndex去找新元素,来替代val)因为是原地修改,并且不考虑超出新长度外的元素,所以我的第一想法是:将找到的元素和最后面的非val值的元素交换位置,然后长度减一。之所以能够在一个数组中操作,是因为fast和slow重合时意味着两个数组相同,不重合时,数组大小由slow定义。,所以区间处理上,middle没必要再取了,并且right必须有效,right = size -1。:通过一个快指针和一个慢指针。
2023-10-11 15:12:04
1093
原创 ROS学习笔记之导航实现02_地图保存和读取
上一节我们已经实现通过gmapping的构建地图并在rviz中显示了地图,不过,上一节中地图数据是保存在内存中的,当节点关闭时,数据也会被一并释放,我们需要将栅格地图序列化到的磁盘以持久化存储,后期还要通过反序列化读取磁盘的地图数据再执行后续操作。在ROS中,地图数据的序列化与反序列化可以通过 map_server 功能包实现。1.map_server简介map_server功能包中提供了两个节点: map_saver 和 map_server,前者用于将栅格地图保存到磁盘,后者读取磁盘的栅格地图并
2021-12-15 01:25:50
11011
5
原创 ROS学习笔记之导航实现01_SLAM建图
准备工作请先安装相关的ROS功能包: 安装 gmapping 包(用于构建地图):sudo apt install ros-<ROS版本>-gmapping 安装地图服务包(用于保存与读取地图):sudo apt install ros-<ROS版本>-map-server 安装 navigation 包(用于定位以及路径规划):sudo apt install ros-<ROS版本>-navigation 新建功能包,并导入依赖: gm
2021-12-15 00:45:40
1363
原创 ROS学习笔记之导航(仿真)
器人是如何实现导航的呢?或换言之,机器人是如何从 A 点移动到 B 点呢?ROS 官方为了提供了一张导航功能包集的图示,该图中囊括了 ROS 导航的一些关键技术:假定我们已经以特定方式配置机器人,导航功能包集将使其可以运动。上图概述了这种配置方式。白色的部分是必须且已实现的组件,灰色的部分是可选且已实现的组件,蓝色的部分是必须为每一个机器人平台创建的组件。导航的关键技术包括以下五点:1、全局地图2、自身定位3、路径规划(全局路径规划+局部路径规划)4、运动控制5、环境感知
2021-11-30 17:53:15
4017
原创 ROS学习笔记之深度相机仿真、小结
通过 Gazebo 模拟kinect摄像头,并在 Rviz 中显示kinect摄像头数据。实现流程:kinect摄像头仿真基本流程: 已经创建完毕的机器人模型,编写一个单独的 xacro 文件,为机器人模型添加kinect摄像头配置; 将此文件集成进xacro文件; 启动 Gazebo,使用 Rviz 显示kinect摄像头信息。 1.Gazebo仿真Kinect1.1 新建 Xacro 文件,配置 kinetic传感器信息<robot name="my
2021-11-30 03:16:03
3193
2
原创 ROS学习笔记之摄像头仿真及显示
通过 Gazebo 模拟摄像头传感器,并在 Rviz 中显示摄像头数据。实现流程:摄像头仿真基本流程: 已经创建完毕的机器人模型,编写一个单独的 xacro 文件,为机器人模型添加摄像头配置; 将此文件集成进xacro文件; 启动 Gazebo,使用 Rviz 显示摄像头信息。 1.Gazebo 仿真摄像头1.1 新建 Xacro 文件,配置摄像头传感器信息有几个要自行修改的地方,基本设置和laser有相同的部分,不做赘述。<robot name="
2021-11-30 02:10:59
2391
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人