自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

luyoung0001@gmail.com的博客

Before was was was, was is is.

  • 博客(143)
  • 收藏
  • 关注

原创 利用 Hexo 搭建个人博客

博客迁移,从 csdn 到 github。

2024-07-06 22:56:54 1041 1

原创 2024.07.05 刷题日记

leetcode 刷题笔记。考试周今天终于结束了,累死了。

2024-07-05 23:30:27 177

原创 2024.07.02 刷题日记

leetcode 刷题笔记。(考试周真浪费学习的时间!)

2024-07-02 23:14:13 408

原创 2024.06.30 刷题日记

leetcode 刷题笔记。

2024-06-30 23:29:37 919 1

原创 2024.06.29 刷题日记

leetcode 刷题笔记,最近在考试周,每天只能做leetcode不到两个小时。

2024-06-29 12:53:39 707

原创 2024.06.28 刷题日记

leetcode 刷题笔记

2024-06-28 23:36:02 440

原创 2024.06.26 刷题日记

leetcode 刷题笔记

2024-06-26 17:44:55 237

原创 2024.06.25 刷题日记

leetcode 刷题笔记。

2024-06-25 22:54:05 921

原创 2024.06.24 刷题日记

leetcode 刷题笔记。

2024-06-24 21:56:45 808

原创 2024.06.23 刷题日记

leetcode 刷题日记。

2024-06-23 17:43:54 1271

原创 2024.06.22 刷题日记

leetcode 刷题笔记。

2024-06-23 14:24:13 367

原创 2024.06.21 刷题日记

leetcode 刷题笔记。

2024-06-21 23:09:58 453

原创 2024.06.20 刷题日记

leetcode 刷题笔记。

2024-06-20 21:07:57 593

原创 2024.06.19 刷题日记

leetcode 刷题笔记。

2024-06-19 21:11:43 619

原创 2024.06.18 刷题日记

leetcode 刷题笔记。

2024-06-18 17:42:47 428

原创 2024.06.17 刷题日记

leetcode 刷题笔记。

2024-06-18 17:27:55 925

原创 2024.06.16 刷题日记

leetcode 题目

2024-06-16 23:05:54 900

原创 mmap() 的几种用法

mmap 是一个非常强大的系统调用,常用于映射文件到内存中,以实现快速和方便的文件访问,也用于进程间通信等多种场景。

2024-06-12 17:50:07 810 2

原创 debugger(七):栈帧(backtrace)

通过读取帧指针(frame pointer)和返回地址来遍历整个调用栈,直到达到main函数为止。每次循环都会输出当前函数的栈帧信息,并更新帧指针和返回地址以跳转到下一个栈帧。

2024-06-11 20:37:04 142

原创 debugger(六):source level 断点

这个可以在所有的编译单元中搜索。对于每一个 **cu**,只需要判断:`(die.has(dwarf::DW_AT::name) && at_name(die) == name)`,如果条件成立,那么就可以获取 **line entry** 了,但是这个 **entry** 并不好用,这一行可能是函数名,我们需要跳过这个 **prologue** 或者没用的行。

2024-06-11 18:37:27 162

原创 debugger(五):source level stepping

返回地址实际上是在调用函数之前的步骤中由调用指令(如 call)隐式处理的,它会将下一条指令的地址(即函数 f() 的地址)压入栈中,作为返回时应该跳转的地址。这里就很清晰了,因为在这之后,紧接着入栈的是 rbp,接着是把 rsp 放入 rbp,当前 rbp 中值就是那时候的 rsp,也是新的栈帧。我们只要把 rbp+8,就能得到它了。

2024-06-11 18:00:33 866

原创 debugger(四):源代码

注意这个 pc 是一个 offset addr,传参的时候一定要转换。思路很简单,首先遍历所有的 cu,然后判断 cu 的 low_pc 和 high_pc,如果在这个 cu 符合,那么就通过 cu 拿到 cu.root。cu.root 是一个根 die,通过它可以遍历所有的 die。之后再判断 die的 tag 是不是一个函数,如果是且包含 pc,那么就是我们要找的函数。

2024-06-10 22:36:15 345

原创 debugger(三):dwarf 文件

在讨论 DWARF 格式的调试信息时,编译单元(Compilation Unit, CU)和行表(Line Table)是两个核心概念。这些信息极大地促进了源码级调试,使调试器能够有效地将执行的机器代码映射回源代码。

2024-06-10 21:46:30 1069

原创 debugger(二):读、写内存以及寄存器

可以看到非常成功,利用 memory write 成功打了一个“断点”。事实上,这个断点只是暂时的,它并没有被记录在 debug 信息系统中,不过这不重要,这只是在验证 memory write 的功能。

2024-06-10 20:40:27 526

原创 debugger(一):打断点的实现以及案例分析

编译后,我们要打断点进行测试,可以看到目前只能传入一个地址,这个地址还是 0x 开头的 16 进制地址,我们对于这个地址丝毫没有头绪,因为我们不知道 std::cerr

2024-05-25 23:32:01 834

原创 C++内存模型

CPU 体系都是基于栈来运行程序,栈中主要存放函数的局部变量、函数参数、返回地址等,栈空间一般由操作系统进行默认分配或者程序指定分配,栈空间在进程生存周期一直都存在,当进程退出时,操作系统才会对栈空间进行回收。

2024-05-20 13:01:08 872

原创 C++:再谈智能指针

通过使用 std::make_unique,确保每次内存分配和对象构造都立即被 unique_ptr 接管。如果构造函数抛出异常,unique_ptr 从未被创建,但因为异常是在 make_unique 内部抛出的,已分配的内存会在抛出异常前由内部机制(通常是函数的栈展开)释放,这就避免了内存泄漏。

2024-05-18 22:22:57 1224

原创 C++调试:函数调用过程和堆栈

最后两条指令是函数结尾处的序曲,通常称作函数的 epilogue(尾声),它们的主要作用是恢复函数开始时保存的状态,并释放栈空间,以便函数可以正确地返回到调用者。

2024-05-17 16:43:00 846

原创 C++调试:内存管理

简而言之,S 和 B 都涉及未初始化的数据,但它们代表的是不同的内存区段。S 不属于 B,但两者都用于未初始化数据的存储,只是大小和存储优化方面有所区别。因此,在处理大型和小型未初始化数据时,编译器和链接器可能会选择将它们分别放在 .bss 或 .sbss 段中。

2024-05-16 22:44:48 249

原创 C++并发:构建线程安全的队列

在 threadsafe_queue 的拷贝构造函数中,尽管传入的 other 对象是一个 const 引用,我们仍然需要从这个 const 对象中复制数据。拷贝构造函数需要访问 other 对象的 data_queue,而为了线程安全,必须先锁定 other 的互斥量。由于 mut 是 mutable 的,即使在 const 上下文中,也能执行锁定操作。

2024-05-15 17:44:36 440

原创 C++并发:等待条件成立

故此,若判定函数有副作用,则不建议选取它来查验条件。 倘若真的要这么做,就有可能多次产生副作用,所以必须准备好应对方法。譬如,每次被调用时,判定函数就顺带提高所属线程的优先级,该提升动作即产生的副作用。结果,多次伪唤醒可“意外地”令线程优先级变得非常高。

2024-05-15 16:10:02 735

原创 C++:并发保护

std::call_once() 保证无论多少线程尝试调用指定的可调用对象,该对象的调用只会执行一次。它通过 std::once_flag 来控制,这个标志协调不同线程对函数调用的访问,确保目标函数只执行一次。

2024-05-14 21:57:45 998

原创 C++并发:锁

在C++中,std::lock 是一个用于一次性锁定两个或多个互斥量(mutexes)的函数,而且还保证不会发生死锁。这是通过采用一种称为“死锁避免算法”的技术来实现的,该技术能够保证多个互斥量按照一定的顺序加锁。

2024-05-14 17:38:26 858

原创 C++:完美转发(二)(std::forward)

C++中常量一般是进入符号表的,只有对其取地址时才会实际分配内存。 调用 f 函数时,其实参是直接从符号表中取值,此时不会发生问题。但当调用 fwd 时由于其形参是万能引用,而引用本质上是一个可解引用的指针。 因此当传入 fwd 时会要求准备某块内存以供解引用出该变量出来。但因其未定义,也就没有实际的内存空间, 编译时可能失败(取决于编译器和链接器的实现)。

2024-05-12 23:30:46 966

原创 C++:完美转发(一)(std::forward)

std::forward 函数模板的实现,这是完美转发的关键机制。完美转发是指在模板函数中将参数维持原样(保持其值类别——左值或右值)传递给另一个函数的技术。std::forward 通常在实现需要将参数转发到其他函数的模板中使用,尤其是在构造函数、函数模板和其他接受任意参数的场景中。

2024-05-12 20:54:02 1176

原创 C++:移动语义(std::move)

移动语义允许资源(如动态内存)在对象间转移,而非复制,这可以显著提高性能,尤其是对于大型对象。移动构造函数和移动赋值操作通常应声明为noexcept以确保在资源转移过程中不抛出异常,这是因为异常可能导致资源泄露或其他问题。实现移动操作时,应确保正确处理自赋值的情况和资源的安全释放。

2024-05-11 23:43:16 930

原创 C++:左值(引用)&右值(引用)

需要注意的是,func() 中的 b 其实是一个左值,换句话说,右值引用如果绑定了一个右值,它会延长这个右值的生命周期。 这种生命周期的延长意味着,尽管原始表达式产生的值是一个右值,一旦它被一个右值引用所绑定,它就不再是一个"即将销毁的临时值",而更像是一个普通的变量。 这允许开发者在保证效率的同时,也能够更灵活地控制这些值。

2024-05-10 22:09:59 1024

原创 C++并发:线程函数传参(二)

当向线程函数传参时,可能发生隐式类型转换,这种转换是在子线程中进行的。需要注意,由于隐式转换会构造临时对象,并将该对象(是个右值)传入线程函数,因此线程函数的形参应该是可接受右值类型的T、const T&或T&&类型,但不能是T&类型。此外,如果源类型是指针或引用类型时,还要防止可能发生悬空指针和悬空引用的现象。

2024-05-10 00:10:13 370

原创 C++并发:线程函数传参(一)

遇到的错误与尝试在 std::thread 构造器中使用不匹配的参数类型有关。错误的根本原因是在创建 std::thread 实例时传递的参数类型与线程函数所期望的参数类型不兼容。因此我们要考虑,传递的参数如何才能正确兼容线程函数期望的参数类型。这正是上面讨论到的一种情况,接着讨论如何优雅的解决这种问题。

2024-05-09 23:39:44 446

原创 macOS DOSBox 汇编环境搭建

这个配置文件在启动 DOSBox 时会被加载并生效。其中的 [autoexec] 部分包含了一些命令,这些命令会在 DOSBox 启动时自动执行。这些命令通常用于配置 DOSBox 的一些初始设置,例如挂载游戏的磁盘镜像、设置运行环境等。

2024-05-05 22:35:14 574 1

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除