自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(47)
  • 资源 (1)
  • 收藏
  • 关注

原创 (零)阅读源码的工具及参考资料

工具分析源码,首先对工具的准备很重要,在windows有阅读源码的利器source insight,但是由于我的日常系统是centos,并且不想在虚拟机下进行分析,所以找了一些linux阅读源码的工具。 我使用的主要工具是:ctags+cscope 接下来我简单介绍一下这些工具的使用ctags的使用在源码根目录执行ctags -R命令,递归的为源码建立tags,在根目录会生成一个Tags的文件,

2017-09-04 09:49:32 1748

原创 (十九)对libevent源码分析的总结

前言在写对libevent源码分析之前,其实已经阅读过几遍libevent源码,结果在分析的时候,还是遇到了一些障碍,不过还好都解决了。由于在真正意义上,这是我第一次分析超过万行的源码,所以可能在分析的过程中,有些遗漏难免发生,后面发现的时候再补上,如果有错误的地方,希望大家指出。总结libevent将定时事件、信号事件、I/O事件都集成到一起,并且可以支持多种多路I/O处理方法,采用了事件驱动机制

2017-09-04 09:36:00 1038

原创 (十八)bufferevent的读写回调函数及对外接口

前言在上一节中,我们介绍了bufferevent实现自动管理的基本思想(水位线机制),在本小节中,我们将介绍bufferevent_readcb、bufferevent_writecb等函数,了解它工作的全过程。bufferevent_readcbstatic voidbufferevent_readcb(int fd, short event, void *arg) { struct

2017-09-03 17:02:53 5786 1

原创 (十七)bufferevent的管理

前言在上节中,我们将evbuffers剩余的内容,比如读/写操作进行了剖析。接下来,我们将对bufferevent进行分析,它主要实现了对缓冲区的自动管理。 在本节中,我们先介绍相关结构体以及一些管理操作,相关代码在evbuffer.c以及event.h文件中。struct bufferevent该结构体用于管理bufferevent。定义如下:struct bufferevent { s

2017-09-03 15:21:28 1018

原创 (十六)evbuffers缓冲区(下)

前言在上节中,我们介绍了evbuffers的部分知识,在本小节中,我们将对剩余的部分一起分析总结。evbuffer_drain在上节中分析的evbuffer_add_buffer中,如果添加源缓冲区到目的缓冲区结尾成功,则会调用evbuffer_drain清除源缓冲区,但是它的功能除了清除整个有效缓冲区以外,还可以清除一部分,接下来我们来看看它的源码:voidevbuffer_drain(stru

2017-09-02 15:05:57 1757

原创 (十五)evbuffers缓冲区(上)

前言evbuffer是libevent的缓冲区部分,它主要是负责缓冲区的构建等操作,而bufferevent主要负责管理输入输出缓冲区,相当于是对evbuffer做的一层抽象,缓冲区对于一个网络库几乎是必需的。我们来介绍关于evbuffer部分,部分主要集中在event.h和buffer.c。evbuffer结构体首先,先了解缓冲区的数据结构:struct evbuffer { u_

2017-09-01 19:44:58 1360

原创 如何理解typedef关键字

前言最近准备开始总结一些东西,当遇到C语言中的typedef时,回想起当时学的时候遇到了一些误区,这里分享出来供大家参考。typedef可能导致的误区在我们初学的时候,无非就是类似像下面这样使用typedef关键字。#include <stdio.h>typedef int INT;typedef struct test{ int a; int b;}Test;int main()

2017-09-28 20:10:38 587

原创 SGISTL源码探究-配接器

前言关于配接器,之前在分析序列式容器时就已经分析过queue和stack,它们也是配接器的一种,通过使用其他容器的接口然后自己加以修饰,形成另外一种容器。除了应用在容器上之外,还有关于应用在仿函数上的配接器,就如我们上一小节分析仿函数时里面的例子一样。还有一种是应用在迭代器上的配接器,等下我们会进行分析。应用于容器的配接器关于这一部分,之前已经分析过queue和stack的实现了,这里就不做赘述了。

2017-09-26 19:18:49 350

原创 SGISTL源码探究-仿函数

前言本小节将介绍STL六大组件之一的仿函数(又称函数对象),在前面分析算法部分时,我们其实已经见识到了仿函数的大量使用(各算法的另一个版本,传入comp仿函数)。关于仿函数的实现,其实就是重载了()运算符,然后调用,所以又称函数对象。接下来我们就来分析该部分。仿函数虽然函数指针也可以完成将各种操作当作参数传入,但是之所以出现了仿函数,是因为函数指针并不能满足STL对抽象的要求,也不能和其他组件很好的

2017-09-26 13:14:52 777

原创 SGISTL源码探究-stl_algo.h中的排序算法

前言在本小节中,我们将分析STL中算法组件的最后一部分:排序算法。排序算法分为内部排序和外部排序。而内部排序中常见的有八种排序算法:直接插入排序、希尔排序、简单选择排序、堆排序、冒泡排序、快速排序、归并排序、桶排序。在SGISTL实现的sort算法中,并不是简单的使用快速排序作为排序算法,而是交叉使用了插入排序、堆排序以及快速排序,并且做了一定的优化,并且只接受迭代器类型为RandomAccessI

2017-09-25 20:21:29 767

原创 SGISTL源码探究-stl_algo.h中的排列算法

前言在本小节中,我们将分析stl_algo.h中的排列算法。可能你使用过STL中的next_permutation求过全排列。比如这样:#include <iostream>#include <algorithm>#include <string>using namespace std;int main(){ string str; cin >> str; sort(

2017-09-24 16:31:39 771 1

原创 SGISTL源码探究-stl_alog.h中的二分查找算法

前言在上一小节中我们分析了stl_algo.h中的部分算法。本小节中我们将继续分析其中关于二分查找类的算法,即lower_bound、upper_bound、binary_search、equal_range。这些算法相比于上一节的要稍微复杂些,如果你对二分法比较了解,这一小节应该也很轻松。STL中的二分查找算法lower_bound使用该函数的前提是传入的区间必须有序,这也是二分法的唯一要求。lo

2017-09-24 16:26:14 575

原创 SGISTL源码探究-stl_algo.h中的基础算法

前言在上一小节中我们分析了stl_algobase.h中的算法,虽然都是一些比较基础的算法,但是了解其中的泛化以及特化的思想是很重要的。在本小节中我们将分析stl_algo.h中的算法,里面的大部分算法也很基础,比较复杂的我们放在另外的小节分析。各算法的实现for_each遍历[first, last),每个元素使用仿函数f进行处理。注意传入的迭代器类型是InputIterator,所以可能不支持赋

2017-09-23 17:59:39 672

原创 SGISTL源码探究-stl_algobase.h中的算法

前言在上一小节中,我们分析了stl_numeric.h中的算法部分。在本小节中,我们将分析stl_algobase.h文件中的算法,里面实现的都是一些比较基本的算法,比如equal、fill、max、swap等,可以从中学习到泛型的思想。stl_algobase.h中的算法iter_swap该函数的作用是交换迭代器指向的两个元素。注意迭代器的类型必须是ForwardIterator及其派生类。 并

2017-09-22 21:23:05 1018

原创 Centos7下一步一步安装YCM插件(附vimrc配置文件)

前言由于博主太naive,使用yum update将内核升级了,直接导致gnome炸了,然后开机就死机,只要进救援模式去把资料备份了,结果一不小心使用rm /home -rf将需要备份的资料也删了。。。然后就开始重装系统了。 YouCompleteMe这款自动补全的插件还是很好用的,但是配置的时候遇到的问题确实可能比较多,等下列出的问题可能也只是少部分,其他的还是需要自己去查。之前就是因为不想重新

2017-09-22 14:04:27 1822

原创 SGISTL源码探究-stl_numeric.h中的数值算法

前言上一小节中,我们对stl中的算法部分做了一个大致的说明。本小节我们将进入到其中关于数值算法的部分,都在stl_numeric.h文件中。废话不多说,直接看源码吧。stl_numericaccumulate注意该算法要求了迭代器的类型至少是InputIterator类型,如果是OutputIterator类型,肯定是不行的。 用于计算元素总和,init加上[first, last)范围内的元素之

2017-09-20 16:03:40 531

原创 SGISTL源码探究-STL中的算法(前言)

前言我们目前已经分析了STL中的六大组件的一半。剩下的还有算法、仿函数、配接器,已经分析了配置器、迭代器、容器部分。接下来进入到剩下的三大组件中最复杂的算法部分,关于STL中的算法,它实现了很多功能,但是分析这部分的时候我只打算选择一部分比较经典的算法进行分析(因为这部分的算法实在是太多了),只要掌握了分析的方法,以后自己遇到其他的STL算法或者感兴趣的,直接阅读源码就行了。概览大致分类STL中的算

2017-09-20 13:58:12 481

原创 SGISTL源码探究-关联式容器:hash_multimap

前言本小节将介绍hash_multimap的源码实现,它与hash_map的不同与map和multimap的不同类似,所以我们可以一边分析它们的不同之处,一边顺便复习hash_map。hash_multimap的实现定义及数据结构#ifndef __STL_LIMITED_DEFAULT_TEMPLATEStemplate <class Key, class T, class HashFcn =

2017-09-19 11:06:32 1003

原创 SGISTL源码探究-关联式容器:hash_multiset

前言在上几节中我们分析了hashtable以及hash_set还有hash_map的实现,hash_set以及hash_map都不允许有重复的key存在,而hashtable提供了允许插入重复元素的操作insert_equal,对应实现的则是hash_multiset以及hash_multimap。 接下来我们先看看hash_multiset的实现,它和hash_set的实现很类似。hash_mu

2017-09-19 10:50:39 981

原创 SGISTL源码探究-关联式容器:hash_map

前言在上一小节,我们分析了hash_set的实现,本小节我们将针对hash_map进行分析。它大部分也是调用的hashtable,不过它与map的区别也是因为底层的实现不同,所以map具有自动排序功能,而hash_map没有。 接下来我们来看看hash_map是如何实现的。hash_map的实现还是分为定义部分及其数据结构、构造函数、常用操作这三部分。关于hash_map的迭代器,是使用的hash

2017-09-19 09:35:30 722

原创 SGISTL源码探究-关联式容器:hash_set

前言在上小节中,我们已经分析了hashtable的实现,它只是hash_set和hash_map的预备知识。在本小节中,我们将进入到关联式容器hash_set的源码中,一窥究竟。hash_set的实现由于hash_set并没有自己定义的迭代器,所以接下来我们先对它的定义部分以及数据结构进行分析,然后是它的构造函数以及常用操作等。定义部分及数据结构#ifndef __STL_LIMITED_DEFAU

2017-09-19 08:58:21 768

原创 SGISTL源码探究-STL中的hashtable(下)

前言在上一小节中,我们介绍了hashtable的基本概念,以及分析了在STL中,hashtable的迭代器、采用的数据结构及它的构造/析构函数,还有部分成员函数。 在本小节中,我们讲继续分析剩下的一些操作,如插入、删除、复制等。插入操作关于插入操作,有大量的重载版本,我们只分析比较关键的函数,其他的可以随便看看。/* insert_unique,插入元素(不允许重复) * 首先先判断加上新增元素

2017-09-18 21:07:22 1043

原创 SGISTL源码探究-STL中的hashtable(上)

前言关于哈希表部分,哈希函数以及解决哈希冲突的方法都有很多种,在本文中不会详细去讨论哈希表的大量知识,而是以SGISTL实现的hashtable为主,所以如果对hashtable不太了解,建议先去网上查阅相关的资料。这里只给出基本的概念。了解哈希表原理基本概念哈希表(hashtable,也称散列表):根据key来访问元素的一种数据结构。它可能先经过哈希函数计算出key,然后通过key访问表中对应ke

2017-09-18 19:49:02 1340

原创 SGISTL源码探究-关联式容器:multimap

前言在本小节中我们将分析multimap的实现。它和map的最大的不同之处在于,map不允许重复的键值插入,而multimap允许重复的键值插入,对应到底层的实现,multimap调用的是insert_equal进行插入操作,而map调用的是insert_unique进行插入操作。 另外还有一个不同之处是multimap不支持下标运算,这个也很合理,因为可能有重复键,访问下标时可能就对应了多个值,

2017-09-17 16:11:09 662

原创 SGISTL源码探究-关联式容器:multiset

前言multiset和set的实现十分相似,除了允许键值重复之外,几乎一样。而实现允许键值重复这一功能的是红黑树中提供的操作insert_equal,接下来我们就进入到它的源码,顺便也复习一下set,看看到底和set有什么不同。multiset的实现#ifndef __STL_LIMITED_DEFAULT_TEMPLATEStemplate <class Key, class Compare =

2017-09-17 15:39:02 735

原创 SGISTL源码探究-关联式容器:map

前言在本小节中,我们将分析map容器,它与set最大的不同就是,它是key-value型的,而set的key和value是同一个。map和set底层都由红黑树实现,map上存储的都是pair,即键值对,存储到红黑树中时,排序依据的就是pair的第一个元素。 之前提到在set中,不允许更改元素的值,而在map中,key值同样不允许修改,但是value可以修改,因为value不涉及到map整体内部结构

2017-09-17 10:46:18 801

原创 SGISTL源码探究-pair的实现

前言本小节将对pair进行源码分析,它经常用于map的实现中,而我们下一节就会分析map的源码,所以有必要在这一小节中,先把pair分析了。 pair的作用就是将两个数据合成一个,而这两个数据可以是不同的类型,这就非常符合key-value这种键值对形式的存储了,接下来我们就进入到它的源码之中。pair的实现pair的实现代码很短,100行不到,但是对map的实现确实提供了非常大的便利。它提供的操

2017-09-17 10:44:08 676

原创 SGISTL源码探究-关联式容器:set

前言在本小节中,我们将分析set容器,它的特性是,所有的元素会根据键值自动在set内部排序,set的键值就是实值,并且不允许两个相同值的元素在set中存在。并且set的元素值不能通过迭代器进行改变,因为一旦改变,就意味着set内部有序就被打破了。 set实现的机制和map一样,同样以红黑树作为底部实现,而关于set的操作,也只用调用红黑树提供的接口就行了。set的实现定义部分#ifndef __S

2017-09-16 19:32:08 585

原创 SGISTL源码探究-STL中的红黑树(下)

前言在上一小节中,我们针对SGISTL中的红黑树的分析完成了一半,接下来的各种操作才是重点的部分。通过以下分析可以了解到红黑树是如何保持平衡的。(STL中实现红黑树定义的重载版本函数太多,我舍去了一部分定义,直接对其声明进行分析,不然篇幅太长)红黑树的常用操作clear上一小节中,析构函数调用了clear,它的实现如下 void clear() { if (node_count != 0)

2017-09-16 17:32:10 772

原创 SGISTL源码探究-STL中的红黑树(上)

前言本小节将进入到SGISTL的红黑树部分。关于红黑树,是一种比较复杂的数据结构,但是并不是特别难。如果对红黑树不太了解,可以去网上查阅相关的资料,因为本文的主要目的是分析STL中的红黑树的源码,和普通的红黑树略有不同,还要复杂一些,需要有一定的基础。基本概念首先什么是二叉搜索树,二叉搜索树即符合任何一个节点的值一定大于其左子树的任何一个节点的值并且小于其右子树的任何一个节点的值(节点的值不允许重复

2017-09-16 14:35:17 1574

原创 SGISTL源码探究-优先级队列

前言在上一小节中,我们分析了heap算法,其实是为了priority_queue优先级队列做准备,它也不是容器,而是配接器,因为它是通过vector来实现的,然后封装了一些vector提供的接口供自己使用而形成的。 优先级队列,即一种特殊的队列,但是它内部的元素没有按照传统队列的先进先出这种顺序排序,而是按照元素的权值进行排列,所以执行出队操作时,出队的是权值最大的元素。priority_queu

2017-09-15 20:01:07 640

原创 SGISTL源码探究-大根堆heap

前言小根堆和大根堆的概念在数据结构都讲过,等下简单的过一下就行了。在SGISTL的实现中,它并不作为一种容器,而是一系列的算法,用于给priority_queue提供支持,使优先级队列能够体现其优先级。 在SGISTL实现heap中,采用的数据结构并不是使用二叉树实现,而是采用隐式表达,即使用数组表示一个堆。能用数组表示这是因为堆总是一棵完全二叉树(没有节点漏洞):即若设二叉树的高度为h,除第 h

2017-09-15 19:14:05 703

原创 SGISTL源码探究-queue配接器

前言在本小节中,我们将分析queue,即队列,这种数据结构的元素符合先进先出(FIFO)的条件。它同stack一样,不算是一种容器,而是采用一种容器(SGISTL中默认是deque)作为底层结构并修改部分接口为自己所用的配接器。queue同stack一样,不支持元素的遍历操作,因此并不需要迭代器。它的所有接口都依靠底层的容器实现。queue源码定义部分#ifndef __STL_LIMITED_DE

2017-09-14 15:09:48 666

原创 SGISTL源码探究-stack配接器

前言迄今为止,我们已经分析了vector、list、deque容器,而stack并不是一个容器,它是依据一种容器作为底层结构,然后根据自己的要求改变容器提供的接口。而在SGISTL的实现中,stack默认是以deque为底部结构,并且封装了一些接口并且stack中没有迭代器,它也并不需要,因为栈这种结构,并不支持遍历等操作,而出栈入栈这些操作,直接使用deque提供的操作,然后自己封装一下就行了。

2017-09-14 15:08:54 622

原创 SGISTL源码探究-deque容器(下)

前言在上一小节中我们介绍了deque容器实现的大致思路以及它内部使用的一些机制,比如存储元素的空间其实是由指针数组里面的指针指向的等。 在本小节中,我们主要介绍一些deque容器封装的一些常用的操作,比如push_back、push_front、insert、erase、clear等。这些函数无非就是根据迭代器内部的first、last、cur的位置来决定进行操作。 所以有必要再重温一下firs

2017-09-13 15:06:30 478

原创 SGISTL源码探究-deque容器(上)

前言deque容器比list以及vector容器都要复杂的多。它用两端都有开口的线性空间来存储数据,这样的话在首部操作数据的效率比vector高,以及虽然它的迭代器是random_access_iterator_tag型的,但是并不是原生指针,需要封装,比list和vector的迭代器都要复杂。它实现的机制是利用二级指针,维护一个指针数组map,然后数组中存储的指针指向具体的线性空间。 map并不

2017-09-12 21:39:23 686

原创 SGISTL源码探究-list容器(下)

前言在上一小节我们主要介绍了list容器的迭代器及数据结构还有结点的分配及释放,构造和析构函数以及一些简单的操作。在本小节中我们将继续分析list容器提供的一些常见操作。insert之前关于list的构造函数的源码中都调用了insert函数,接下来,我们就来分析它,要记得,STL规定insert函数都是向前插入。 它有多个重载版本。在指定位置前插入一个结点iterator insert(itera

2017-09-11 20:10:38 413

原创 SGISTL源码探究-list容器(上)

前言在本小节中,我们将介绍序列式容器之一的list,它采用的数据结构是环状双向链表,而前面分析的vector是线性存储的。list对于插入数据,删除数据的效率很高,并且迭代器不会轻易失效。但是它的迭代器并不像vector那样是原生指针,所以它的类型可能并不是random_access_iterator_tag型,并且需要自己内嵌那五种相应型别。那么接下来,我们就正式进入到list容器的源码。 首先

2017-09-11 13:13:44 396

原创 SGISTL源码探究-vector容器(下)

前言在本小节中,我们将接着上一下节,继续分析关于vector的内存控制,及一些常用操作部分。vector的内存控制引入在上一节中我们给出了一个简单的例子,借助这个例子已经大约明白了vector管理内存的机制。接下来,我们就来看看push_back这以操作。push_backvoid push_back(const T& x) { /* 判断是否到vector最大容量 * 若没有,则构造该对

2017-09-10 12:42:05 572

原创 SGISTL源码探究-vector容器(上)

前言vector容器应该算是最常用的容器之一了,它是序列式容器的一种,即元素可被排序。vector被称为动态数组,可以随着元素的加入,内部的大小自行扩充。可能你对vector的机制有所耳闻,比如每次扩充时,扩充当前容量的2倍等。接下来,我们就进入到它的源码来看看vector是如何实现的。我们将它分为四部分进行分析,vector的迭代器,vector的内存分配及构造,vector的内存控制以及一些常用

2017-09-09 17:22:38 683 5

MASMforWindows2015

好用的汇编编译器

2016-09-19

空空如也

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

TA关注的人

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