自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(56)
  • 收藏
  • 关注

原创 深入理解 C++ 智能指针

智能指针和RAII(资源获取即初始化)是两个重要的概念,用于管理动态内存和其他资源。智能指针是一种自动管理内存的工具,通过引用计数或其他机制来确保资源的正确释放,从而避免内存泄漏和悬空指针的问题。RAII则是一种编程范式,利用对象的生命周期来管理资源的获取和释放,通过对象的构造函数获取资源,而在对象销毁时自动释放资源,从而确保资源的正确管理。本文介绍了C++中常见的智能指针类型,包括std::unique_ptr和std::shared_ptr,以及如何使用它们来避免内存泄漏和提高程序的安全性。

2024-06-10 18:55:07 704 5

原创 Linux线程:管理与控制

线程是操作系统能够进行调度的最小单位,是进程内的一个执行单元。它负责在程序里独立执行一个控制流(线程流),拥有独立的执行栈和程序计数器(PC),用于保存线程上下文信息。线程本身不拥有系统级的独立资源(如独立的内存空间、文件描述符表等),而是与同属一个进程的其他线程共享进程所拥有的全部资源。线程拥有一些运行中必不可少的资源,如程序计数器、一组寄存器和栈,以支持其独立的执行路径。在Linux中,线程是通过在相同的地址空间内创建多个结构体来实现的,这些结构体表示了线程的状态和相关信息。

2024-05-28 21:25:51 1015 3

原创 操作系统中内存的管理方式

Linux操作系统通过复杂的内存管理系统来管理物理内存和虚拟内存。在这个系统中,物理内存被抽象为struct page结构体,这是Linux内核中表示物理内存页的基本数据结构。内存管理的一个关键组成部分是内存页(memory page)。物理内存被划分为固定大小的页(通常是4KB),每个页都由一个`struct page`来表示。这个结构体包含了关于内存页的各种信息,如页是否在使用、页的内容是否在磁盘上(即交换出去)、页被哪个进程或哪些进程使用等。

2024-05-21 21:01:25 988 6

原创 Linux信号机制

Linux信号是操作系统中用于进程间通信、处理异常等情况的一种机制。它是由操作系统向一个进程或者线程发送的一种异步通知,用于通知该进程或线程某种事件已经发生,需要做出相应的处理。每个信号都有一个名字。这些名字都以三个字符SIG开头。在头文件中,这些信号都被定义为正整数(信号编号)。没有一个信号其编号为 0。POSIX 标准信号(Standard Signals):这些是传统的 Unix 信号,包括SIGINT(通常由 Ctrl+C 产生)、SIGTERM(请求终止)、SIGKILL。

2024-05-17 21:20:07 1070 3

原创 System V IPC(进程间通信)机制详解

在共享内存模型中,进程A和进程B都可以直接访问同一块物理内存区域(即“共享区”)。这意味着数据不需要通过系统调用或其他中间层进行复制或传输,从而减少了数据传输的开销。共享内存通过允许进程直接访问同一块物理内存区域,减少了数据传输和I/O操作的开销,降低了延迟,从而提高了进程间通信的效率。当A进程需要与B进程通信时,只需要把共享区的虚拟地址与物理地址的映射写入两进程的页表中。因此,进程A可以对该物理地址直接进行写入;而B进程则是通过页表的映射关系,从该物理地址直接进行读取。

2024-05-14 21:28:38 847 17

原创 Linux进程间通信——匿名管道和命名管道

Linux中的“万物皆文件”原则使得管道也被抽象为一个文件对象。这意味着进程可以通过标准的文件I/O操作(如read、write等)来访问管道,从而实现进程间的通信。因此我们可以说管道是基于文件的,让不同进程看到同一份资源的通信方式。对于管道而言,它允许一个进程的输出直接作为另一个进程的输入,而无需使用临时文件或其他中间存储机制。具体来说,管道在内存中创建了一个缓冲区,用于存储从写入端流向读取端的数据。这个缓冲区对于进程来说是透明的,进程只需要通过标准的文件I/O操作(如readwrite等)来访问它。

2024-05-13 08:00:00 620 6

原创 Linux动态库与静态库解析

在Linux系统开发中,库文件扮演着至关重要的角色。它们提供了程序运行所需的各种功能,使得开发者能够高效地复用代码,减少重复劳动。库文件通常分为动态库(也称为共享库)和静态库两种类型,它们在程序链接和运行阶段扮演着不同的角色。

2024-05-07 16:43:17 1145 4

原创 理解Linux文件系统

传统的磁盘与文件系统之应用中,一个分区就是只能够被格式化成为一个文件系统,所以我们可以说一个 filesystem 就是一个 partition。但是由于新技术的利用,例如我们常听到的LVM与软件磁盘阵列(software raid), 这些技术可以将一个分区格式化为多个文件系统(例如LVM),也能够将多个分区合成一个文件系统(LVM, RAID)! 所以说,目前我们在格式化时已经不再说成针对 partition 来格式化了, 通常我们可以称呼一个可被挂载的数据为一个文件系统而不是一个分区。

2024-05-01 22:04:05 3949 5

原创 Linux文件系统中的软硬链接

在文件系统中,链接(Link)是一个重要的概念,它允许用户或系统通过不同的路径名访问同一文件或目录。链接分为硬链接(Hard Link)和软链接(Soft Link)两种。硬链接允许一个文件拥有多个文件名。这些文件名指向同一个inode,而该inode节点包含了文件的元信息(如文件大小、权限、所有者等)以及指向文件数据的指针,且文件所在的目录的inode与block的容量不发生改变。与硬链接不同,软链接不直接指向文件的inode节点,而是通过路径名来访问文件。

2024-05-01 19:45:59 822 1

原创 C++类型转换攻略

在C++编程中,类型转换(Type Conversion)是一个核心概念,它指的是将一个数据类型的值转换为另一个数据类型的值的过程。这种转换可能是隐式的(由编译器自动执行),也可能是显式的(由程序员通过特定的语法明确指示)。类型转换在编程中至关重要,因为它允许程序员灵活地处理不同数据类型的数据,并能够在需要时将它们转换为兼容的类型,以便进行进一步的计算或操作。

2024-04-30 16:45:02 1516 1

原创 Linux下的进程管理:创建、终止、切换与等待

进程管理是操作系统中不可或缺的核心功能之一,它负责控制和协调系统中各个进程的执行,确保它们能够高效、安全地并发运行。进程的创建、终止、切换与等待更是管理的关键环节。这些操作不仅影响单个进程的生命周期,更直接关系到系统资源的分配与利用效率。

2024-04-24 21:16:26 4377 8

原创 Linux进程地址空间及其页表

进程地址空间是指每个进程在计算机内存中所占用的地址空间。它本质上是一种虚拟地址空间,是进程看待内存的方式,抽象出来的一个概念,由操作系统提供。这种地址空间不是物理地址,而是由内核中的结构体mm_struct表示,用于在进程控制块中完成各个数据区域的划分,并通过页表映射到物理内存上。每个进程都有自己独立的地址空间,意味着每个进程都有自己的内存地址范围,不会与其他进程冲突。这种独立性有助于防止地址的随意访问,保护物理内存与其他进程。同时,将进程管理和内存管理进行解耦合,保证进程的独立性。

2024-04-23 19:13:08 1223 2

原创 Linux环境变量深度解析

在Linux操作系统中,环境变量是一种特殊的变量,用于存储系统或用户配置的信息。它们以键值对(key-value pair)的形式存在,可以在整个系统中被不同的程序和脚本访问和使用。环境变量通常用于存储路径、系统设置、语言环境等关键信息,以便程序能够正确地运行和交互。环境变量具有全局性,一旦设置,就可以被当前用户或整个系统的所有进程所访问。这使得环境变量成为了一种非常有效的配置和管理系统资源的方式。

2024-04-20 19:44:55 2057 4

原创 Linux进程状态深度解析:探索进程的生命周期

在Linux系统中,进程状态是多种多样的,它们各自代表了进程的不同执行阶段和资源占用情况。这些状态可以大致分为几类:为了弄明白正在运行的进程是什么意思,我们需要知道进程的不同状态。一个进程可以有几个状态(在 Linux内核里,进程有时候也叫做任务)。"X (dead)"可执行状态(R):进程正在运行或准备在CPU上运行。这通常表示进程处于可执行状态,等待获得CPU资源以执行其代码。可中断的睡眠状态(S):进程处于可中断的睡眠状态。这意味着进程正在等待某个条件成立,比如等待I/O操作完成。

2024-04-07 16:44:43 2768 9

原创 std::function与std::bind:C++中的函数包装与绑定

std::function是一个通用的、多态的函数包装器,它可以保存、复制和调用任何Callable目标——函数、lambda表达式、bind表达式或其他函数对象。这使得我们能够以统一的方式处理各种可调用对象,无需关心它们的具体类型或签名。通过`std::function`,我们可以将函数作为参数传递给其他函数,或者将函数存储在容器中,实现更为灵活和模块化的代码设计。而std::bind则是一种生成可调用对象的方式,它可以将一个可调用对象与其参数绑定在一起,生成一个新的可调用对象。这个新的可调用

2024-04-07 12:40:48 853

原创 深入理解C++ lambda表达式:用法、特性与最佳实践

在C++中,lambda表达式是一种可以定义匿名函数的语法结构,允许在需要函数作为参数的地方直接定义和传递函数,从而提高了代码的简洁性和可读性。如果lambda表达式的体只有一个返回语句,并且该语句的类型是明确的,那么编译器可以自动推断出lambda的返回类型。其次,lambda表达式可以作为参数传递给其他函数,特别是在STL算法中,lambda表达式可以作为谓词(Predicate)使用,实现更加灵活的功能。在C++的lambda表达式中,返回类型可以是隐式推断的,也可以显式指定。

2024-04-06 17:20:42 1250 2

原创 C++11中auto与decltype的区别与联系深入解析

auto是C++11中引入的一个关键字,它用于在声明变量时让编译器自动推导出变量的类型。在这里,是一个表达式,编译器会根据该表达式的类型来推导的类型。decltype的主要功能是允许编译器在编译时期根据给定的表达式来推断其类型,而不仅仅是基于变量的初始化表达式。

2024-04-06 15:41:17 1052

原创 C语言中的数组与函数指针:深入解析与应用

从字符串数组的基础知识出发,逐步探讨函数指针的概念与应用。我们将首先回顾字符串数组的基本概念和应用场景,然后逐步引入函数指针的概念,并详细阐述其在编程中的高级应用和灵活性。通过这个过程,我们希望读者能够深入理解从处理数据(字符串数组)到处理代码(函数指针)的思维转变,并学会将这两种强大的工具结合起来,实现更复杂、更灵活的编程逻辑。

2024-04-03 21:32:19 1423 5

原创 深入C语言:探究static关键字的奥秘

当用于不同的上下文环境时,`static`关键字具有不同的意思。当用于函数定义时,或用于代码块之外的变量声明时,`static`关键字用于修改标识符的链接属性(从 `external` 变为 `internal` ),但标识符的存储类型和作用域不受影响。用这种方式声明的函数或变量只能在声明它们的源文件中访问。当用于代码块内部的局部变量的声明的时候,`static`用于修改变量的存储类型,从自动变量修改为静态变量,但变量的链接属性和作用域不受影响。用这种方式声明的变量在程序执行之前创建,并在程序的整个

2024-04-03 20:02:20 657 1

原创 布隆过滤器:基于哈希函数的原理、应用解析

布隆过滤器(Bloom Filter) 是一种空间效率极高的概率型数据结构,它利用位图和哈希函数来快速判断一个元素是否属于某个集合。布隆过滤器不是传统意义上的过滤器,它不能完整地存储数据,而是以一种紧凑的方式表示数据可能存在的集合。

2024-04-01 19:34:53 1169 6

原创 深入探索位图技术:原理及应用

虽然位图在图形处理中也常被提及,但在此上下文中,我们需要明确区分两种不同类型的“位图”:一种是数据结构中的位图,如上所述,它主要用于数据的高效存储和检索;当我们要标记第n个数据元素是否存在时,我们只需要找到对应的整数(通过n除以32得到整数索引),然后在该整数中找到对应的二进制位(通过n对32取余得到位索引),并将其设置为0或1。在上面的例子中,如果使用一个整型数组来存储集合中的元素,每个整数需要4个字节(假设是32位系统),那么存储1亿个整数需要大约400MB的空间。如果是1,表示该整数存在于集合中;

2024-03-31 21:10:18 932 15

原创 C++运算符重载中的引用返回

在C++中,对于自定义类型,重载运算符时返回引用是一个常见的做法,特别是针对类似+=、-=等复合赋值运算符。通过返回左侧操作数的引用,可以实现链式调用和保持与内置类型相似的行为,增强代码的可读性和一致性。这不仅增加了内存分配和释放的开销,还可能导致不必要的对象复制,降低了代码的效率。通过返回引用,我们可以直接修改并返回原始对象,避免了这些额外的开销。对于自定义类型,重载这些运算符以返回引用可以保持与内置类型相似的行为,这有助于保持代码的语义一致性和可读性。类重载了赋值运算符,使其返回自身的引用。

2024-03-26 16:27:33 1235 15

原创 红黑树进阶:正向与反向迭代器的实现及map、set的封装实践

map和set是两种常见的数据结构,它们分别用于存储键值对和无序集合。红黑树作为一种高效的平衡搜索树,非常适合用于封装这两种数据结构。通过红黑树的特性,我们可以保证map和set在插入、删除和查找操作时的性能稳定且高效。此外,红黑树的有序性也使得map和set在遍历元素时能够按照特定的顺序进行,满足了更多实际应用的需求。迭代器是一种设计模式,它允许我们顺序访问容器中的元素。对于红黑树来说,设计高效的迭代器是实现其封装Map和Set的关键之一。通过迭代器,我们可以方便地遍历红黑树中

2024-03-25 18:27:19 1190 17

原创 从哈希桶角度看 unordered_map 与 unordered_set 的实现

在C++中,当使用等无序容器时,哈希函数起着至关重要的作用。默认的哈希函数对于许多类型都工作得很好,但有时对于自定义类型或特殊需求,默认的哈希函数可能不是最优的,甚至可能导致性能下降或哈希冲突过多。为特定类型设计哈希函数对于自定义类型,需要提供一个哈希函数,该函数接受自定义类型的对象作为参数,并返回一个足够大的整数值。不同的对象尽可能映射到不同的哈希值。相同的对象总是映射到相同的哈希值。哈希函数的计算应该尽可能快。

2024-03-19 20:24:48 2672 2

原创 哈希技术解析:从哈希函数到哈希桶及其迭代器的全面指南

哈希表(Hash Table)是一种非常重要的数据结构,它基于哈希函数将键(Key)映射到值(Value)上,从而实现对数据的快速存储、查找和删除。在哈希表中,数据并不是按顺序存储的,而是根据哈希函数计算出的键的哈希值,确定数据在表中的位置。由于哈希函数的设计使得键与位置之间存在直接对应关系,因此哈希表在查找、插入和删除操作上的平均时间复杂度可以达到O(1),即常数时间复杂度。这使得哈希表在处理大规模数据时具有极高的效率。

2024-03-19 18:15:41 1261 1

原创 深入解析红黑树(RB-Tree):原理、操作及应用

红黑树作为一种自平衡的二叉搜索树,在计算机科学领域中占据着重要的地位。它的设计旨在在维持树的平衡性的同时,保证各种操作的时间复杂度始终稳定在较低水平。红黑树的灵活性和高效性使得它成为众多编程语言和系统实现中不可或缺的数据结构之一。本文将带领读者深入探究红黑树的结构与原理。(c++实现)

2024-03-17 20:28:28 1317 2

原创 细说C++反向迭代器:原理与用法

通常,反向迭代器在内部持有一个指向容器末尾之后位置的迭代器,或者一个指向容器第一个元素之前的迭代器,这取决于容器的具体实现。本文将详细介绍C++中反向迭代器的概念、原理和使用方法,并通过模拟实现一个简单的反向迭代器来加深读者对反向迭代器的理解。通过本文的学习,读者将能够掌握反向迭代器的基本用法,并能够在实际编程中灵活运用反向迭代器来处理各种需要逆向遍历容器的场景。在C++中,反向迭代器是一种特殊的迭代器,它允许我们按照相反的顺序遍历容器中的元素。在标准库中的迭代器类型中,这通常是成立的。

2024-03-15 20:48:31 1470 6

原创 探索仿函数(Functor):C++中的灵活函数对象

仿函数(Functor)是一种行为类似函数的对象,它可以被用作函数并接受参数。在C++中,仿函数通常是重载了函数调用运算符operator()的类对象。通过重载operator(),仿函数可以像函数一样被调用,并且可以保存状态信息。按照操作数划分:假定某个类有一个重载的operator(),而且重载的operator()要求获取一个参数,我们就将这个类称为一元仿函数(unary functor);如果重载的operator()要求获取两个参数,就将这个类称为二元仿函数(binary functor)。

2024-03-15 18:48:28 1098 3

原创 深入解析C++树形关联式容器:map、set及其衍生容器的使用与原理

关联式容器是C++标准库中的一种重要数据结构,它允许我们存储键值对(key-value pair)或单独的元素,并基于键(key)来快速访问或检索对应的值(value)或元素。关联式容器在多种场景下发挥着至关重要的作用,特别是在需要高效查找、插入和删除元素时。它们为程序员提供了便捷的工具,可以简化复杂的操作,并优化程序性能。

2024-03-13 18:34:47 1602 12

原创 深入探索AVL树:优雅的自平衡二叉搜索树

AVL树是一种自平衡的二叉搜索树,其在每个节点上维护一个平衡因子(Balance Factor),用于确保树的高度保持在较低水平( 即保持在O(log n) )从而提高性能。定义每个节点的平衡因子(Balance Factor)是 -1、0 或 1。左右子树高度之差(简称平衡因子)的绝对值不超过1(-1/0/1)。左子树和右子树都是AVL树。// 该节点的左孩子// 该节点的右孩子// 该节点的双亲int _bf;

2024-03-12 19:12:49 1041 17

原创 深入了解二叉搜索树:原理、实现与应用

在计算机科学中,数据结构是构建算法和程序的基础。其中,二叉搜索树(Binary Search Tree,简称 BST)作为一种常见的数据结构,在很多应用中发挥着重要作用。它具有以下特点:每个节点最多有两个子节点,左子节点的值小于父节点的值,右子节点的值大于父节点的值。这一特性使得二叉搜索树具有快速的查找、插入和删除操作。

2024-03-10 20:12:40 1478 37

原创 【C++私房菜】序列式容器的迭代器失效问题

在实际编程中,当对listvector以及string进行插入或删除操作时,需要格外小心,避免在迭代器失效的情况下继续使用迭代器。如果需要在循环中对容器进行插入或删除操作,可以考虑使用迭代器的insert和erase方法,并注意更新迭代器的位置,以避免迭代器失效问题。一句话就能总结解决迭代器失效问题:在使用前,对迭代器重新赋值即可。

2024-02-28 20:04:47 1466 66

原创 【C++私房菜】面向对象中的多态

在C++中,重载、覆盖(重写)和隐藏(重定义)都是面向对象编程中的概念,用于处理函数的多态性。重载(Overloading)定义:重载是指在同一个作用域内,使用相同的函数名但具有不同的参数列表的情况。函数重载可以根据参数的类型、顺序和个数进行区分。特点:函数名相同,参数列表不同。返回值类型可以相同也可以不同。发生在同一个类或命名空间中。覆盖(重写,Override)定义:覆盖是指在派生类中重新实现基类中已经存在的虚函数。

2024-02-24 21:06:06 1360 37

原创 【C++私房菜】面向对象中的多重继承以及菱形继承

多重继承(multiple inheritance)是指从多个直接基类中产生派生类的能力。多重继承的派生类继承了所有父类的属性。尽管看上去与单继承没有什么区别,但是多个基类交织混合产生的细节会带来错综复杂的设计问题与实践问题。菱形继承是多继承的一种特殊情况。

2024-02-23 18:20:39 1403 38

原创 【C++私房菜】面向对象中的简单继承

一个派生类对象包含多个组成部分:一个含有派生类自己定义的(非静态)成员的子对象,以及一个与该派生类继承的基类对应的子对象,如果有多个基类,那么这样的子对象也有多个。如果基类对象不是派生类对象的一部分,则它只含有基类定义的成员,而不含有派生类定义的成员。类似的,如果我们将一个派生类对象赋值给一个基类对象,则实际运行的赋值运算符也是基类中定义的那个,该运算符同样只能处理基类自己的成员。表达式的静态类型是编译时总是已知的,它是变量声明时的类型或表达式生成的类型:动态类型则是变量或表达式表示的内存中的对象的类型。

2024-02-23 14:42:06 1202 33

原创 【Linux】make和makefile详解

当谈论到 Linux 中的软件构建工具时,不得不提到 Makefile。Makefile是一种文件,它包含了一组规则,用于指导构建系统在源代码中生成可执行文件或库。它是使用GNU Make软件的标准格式。Makefile 的主要目的是描述代码文件之间的依赖关系以及如何构建以达到特定目标。通过定义规则和命令,开发人员可以轻松地管理项目的复杂构建过程。Makefile 带来的好处就是——“自动化编译”,一旦写好,只需要一个 make 命令,整个工程 完全自动编译,极大的提高了软件开发的效率。

2024-02-01 17:30:52 1514 4

原创 【C++私房菜】类和对象详解

在 C++中,我们通过定义一个类(class)来定义自己的数据结构。一个类定义了一个类型,以及与其关联的一组操作。类机制是 C++最重要的特性之一。实际上,C++最初的一个设计焦点就是能定义使用上像内置类型一样自然的类类型(class type)。类是 C++中面向对象编程(OOP)的核心概念之一。

2024-02-01 17:29:16 930 4

原创 【 C++私房菜】模板的入门与进阶

函数模板(function template)是通用的函数描述,也就是说,它们使用泛型来定义函数,其中的泛型可用具体的类型(如 int、double) 替换。通过将类型作为参数传递给模板。可使编译器生成该类型的函数。由于模板允许以泛型(而不是具体类型)的方式编写程序。因此有时也被称为通用编程,由于类型是用参数表示的,因此模板特性有时也被称为参数化类型(parameterized types)。下面介绍为何需要这特性以及其工作原理。

2024-01-27 22:15:39 1157 7

原创 【C++私房菜】new/delete、定位new及内存分配

C++内存管理以及new delete ,定位运算符……

2023-11-12 12:24:24 643 17

原创 【Linux】Shell基本命令——操作系统

命令行和sheill这两个概念常常是令人困惑的,在很多不正式的场合,这两个名词代表着相同的概念,即命令行解释器。然而从严格意义上讲,命令行指的是供用户输入命令的界面,其本质只是接受输入,然后把命令传递给命令解释器。后者就是shell。从本质上讲,shell是一个程序,它在用户和操作系统之间提供了一个面向行的可交互接口。用户在命令行中输入命令,运行在后台的Shell把命令转换成指令代码发送操作系统。shell提供了很多高级特性,使得用户和操作系统间的交互变得简单。

2023-11-12 10:37:26 345 3

空空如也

空空如也

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

TA关注的人

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