C-C++
喜欢恋着风
这个作者很懒,什么都没留下…
展开
-
STL常见问题
vectorvector中: reserve()函数:预先分配一块较大的指定大小的内存空间,其中n为分配空间的大小; 预留一定的空间,如果n < capacity(),并不会减少空间; void reserve(size_type n) { if (capacity() < n) { const size_type old_size = size原创 2017-06-16 09:15:15 · 205 阅读 · 0 评论 -
布隆过滤器及其实现
简介(Bloom Filter)是由布隆(Burton Howard Bloom)在1970年提出的。loom Filter是一种空间效率很高的随机数据结构,它实际上是由一个很长的二进制向量和一系列随机映射函数组成,布隆过滤器可以用于可以快速且空间效率高的判断一个元素是否属于一个集合;用来实现数据字典,或者集合求交集:优点: 空间效率和查询时间都远远超过一般算法;缺点: 有一定的误识别率(假原创 2017-08-10 18:22:08 · 764 阅读 · 0 评论 -
struct/class等内存字节对齐问题详解
问题引入定义一个结构体的一般形式为:struct 结构体名{ // 类型说明符 成员名;};例如下面的结构体:struct Stu{ int id; char sex; float hight;};那么一个这样的结构体变量占多大内存呢?也就是cout<<sizeof(Stu)<<endl;输出时多少呢? 在了解字节对齐之前会想当然的认为:sizeof(Stu原创 2017-08-11 10:00:54 · 617 阅读 · 0 评论 -
x86架构下,页面大小为什么是4K?
前提:32位逻辑空间的计算机OS,两级页表,每个页中每个条目占4bytes,即32位的数据 以上前提是目前X86架构的32为系统的真实情况;设页大小为X(byte),则X/4为每个页可以存取的条目的个数,两级页表的地址转换关系如下图所示:假设在一个32位的条目中存放此内存的地址,则2*log2(X/4)就是图1中,p1+p2的位数;2^(p1 + p2):系统可以寻址多少个页面 (X / 4)^原创 2017-08-11 15:37:41 · 6546 阅读 · 2 评论 -
Linux(C/C++)下的文件操作open,fopen
open是Linux下的底层系统调用函数,fopen是C/C++下的标准I/O库函数,带输入/输出缓冲。Linux下的fopen是open的封装函数,fopen最终还是要调用底层的系统调用open。所以在Linux下如果对设备进行明确的控制,最好使用底层系统调用(open)。open对应的文件操作有:close, read, write,ioctl 等。 fopen 对应的文件操作有:fclose原创 2017-08-11 16:03:23 · 1664 阅读 · 0 评论 -
动态内存与智能指针及其实现
详解请参照智能指针详解本文主要依据C++ primer的基础知识分析智能指针,并最后给出智能指针的实现;shared_ptrshared_ptr允许多个指针指向同一个对象shared_ptr是实现为模板,当创建一个智能指针时,必须提供额外的信息—-指针可以指向的类型;最安全的分配和使用动态内存的方法是调用一个名为make_shared的标准库函数,此函数在动态内存中分配一个对象并初始化它,返回原创 2017-06-13 14:46:40 · 802 阅读 · 0 评论 -
Shared_ptr详解
shared_ptr在boost库中已经有多年了,C++11又为其正名,把他引入了STL库,放到了std的下面,可见其颇有用武之地;但是shared_ptr是万能的吗?有没有什么样的问题呢?本文并不说明shared_ptr的设计原理,也不是为了说明如何使用,只说一下在使用过程中的几点注意事项。用法shared_ptr<int> sp(new int(10)); //一原创 2017-08-13 21:12:20 · 1434 阅读 · 0 评论 -
STL空间配置
SGI STL有两级配置器:第一级配置器的allocate() 和 realloc()都是在调用malloc() 和 realloc()不成功后,改调用oom_malloc() 和 oom_realloc(),后两者都有内循环,不断调用“内存不足处理例程”,期望在某次调用之后,获得足够的内存来完成任务,但如果“内存不足处理例程”未被客端设定,oom_malloc() 和 oom_realloc()原创 2017-08-07 11:40:04 · 220 阅读 · 0 评论 -
常见缓存算法和LRU的C++实现
对于web开发而言,缓存必不可少,也是提高性能最常用的方式。无论是浏览器缓存(如果是chrome浏览器,可以通过chrome:://cache查看),还是服务端的缓存(通过memcached或者redis等内存数据库)。缓存不仅可以加速用户的访问,同时也可以降低服务器的负载和压力。那么,了解常见的缓存淘汰算法的策略和原理就显得特别重要。常见的缓存算法LRU (Least recently used原创 2017-09-04 10:56:36 · 788 阅读 · 0 评论 -
Windows栈大小
一般来说,我们所用的内存有堆和栈之分,其余的我们很少控制,栈的速度快,但是空间少,不灵活;而堆的空间几乎可以满足任何要求:灵活,但是相对速度要满了很多,并且在VC中堆是人为控制的,new了就要delete,否则很容易产生内存泄漏等问题; OS 栈的字节数 bits digits 以兆为单位的值 Linux 8192K <=62407 <= 18786 默认8M原创 2017-07-31 17:45:59 · 4975 阅读 · 1 评论 -
关于内联函数的几点总结以及构造析构是否可以是inline的
为什么要引入内联函数(内联函数的作用)用它替代宏定义,消除宏定义的缺点。宏定义使用预处理器实现,做一些简单的字符替换因此不能进行参数有效性的检测。另外它的返回值不能被强制转换为可转换的合适类型,且C++中引入了类及类的访问控制,在涉及到类的保护成员和私有成员就不能用宏定义来操作。1、内联函数与宏定义的区别:内联函数在编译时展开,可以做一些类型检测处理。宏在预编译时展开;内联函数直接嵌入到目标代码中原创 2017-06-27 20:45:01 · 5838 阅读 · 0 评论 -
C++虚函数表解析
本文内容参考自陈皓C++ 虚函数表解析前沿C++的虚函数主要是实现了多态的机制,关于多态,简而言之,就是父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类指针有“多种形态”,这是一种泛型技术。所谓泛型技术,说白了就是使用不便的代码来实现可变的算法,比如:模板技术,RTTI技术,虚函数技术,要么试图做到编译时决议,要么试图做到运行时决议;虚函数表对C++ 了解原创 2017-06-18 20:45:15 · 211 阅读 · 0 评论 -
函数对象和函数指针
C++的函数调用语法实体有函数、类似于函数的宏、函数指针、仿函数(函数对象)。函数调用方式有:直接调用:通过函数名直接调用函数,函数起始地址成为指令的一部分,因此编译器就能确定调用了哪个函数;间接调用:通过函数指针来调用函数,函数起始地址位于内存或寄存器的某处,因此,到运行期才能确定调用哪个函数。所以仿函数比函数指针快,仿函数在编译器就确定好了;内联调用:直接在调用处展开函数代码,在编译期进行原创 2017-08-29 15:54:21 · 599 阅读 · 0 评论 -
C++面试题(~01)
冯诺依曼体系结构冯诺依曼体系结构用于存储程序方式,指令和数据不加区别混合存储在同一存储器中。有如下特点:一律用二进制数表示数据和指令;顺序执行程序。执行前,将需要的程序和数据先放入存储器(PC为内存),当执行时把要执行的程序和要处理的数据按顺序从存储器中取出指令并一条一条执行,称作顺序执行程序;计算机硬件由运算器、控制器、存储器、输入设备和输出设备五大部分组成;编程测试机器大小端存储请写一个原创 2017-08-07 22:38:39 · 480 阅读 · 0 评论 -
C++面试题(~10)
C++中忘记用delete释放内存,如何防止内存溢出使用智能指针使用RAII方法Kill -9 pid 直接杀死进程。。。原创 2017-09-18 16:20:17 · 626 阅读 · 0 评论 -
哈希表的设计与实现
简介哈希表,也称散列表,是实现字典操作的一种有效的数据结构。尽管在最坏的情况下,散列表查找一个元素的时间复杂度与链表中查找的时间相同,达到了O(n),然而实际应用中,散列表查找的性能是极好的,在一些合理的假设下,在散列表中可以查找一个元素的平均时间是O(1)。哈希表的精髓在于哈希二字上面,也就是数学里面常用到的映射关系,它是通过哈希函数将关键字映射到表中的某个位置上进行存放,以实现快速插入和查询的。原创 2017-08-03 17:12:50 · 11247 阅读 · 0 评论 -
给定一个函数rand()能产生0到n-1之间的等概率随机数,问如何产生0到m-1之间等概率的随机数?
题目:给定一个函数rand()能产生1到n之间的等概率随机数,问如何产生1到m之间等概率的随机数?先把问题特殊化,例如原题变为给定一个函数rand5(),该函数可以随机生成1-5的整数,且生成概率一样。现要求使用该函数构造函数rand7(),使函数rand7()可以随机等概率的生成1-7的整数。很多人的第一反应是利用rand5() + rand()%3来实现rand7()函数,这个方法确实可以产生1原创 2017-08-09 22:52:38 · 3549 阅读 · 0 评论 -
蓄水池抽样算法 (Reservoir Sampling Algorithm)
蓄水池抽样算法简介蓄水池抽样算法是随机算法的一种,用来从N个样本中随机选择K个样本,其中N非常大(以至于N个样本不能同时放入内存)或者N是一个未知数。其时间复杂度为O(N),包含下列步骤 (假设有一维数组 S, 长度未知,需要从中随机选择 k 个元素, 数组下标从 1 开始), 伪代码如下:array R[k]; // resultinteger i, j;// fill the reser原创 2017-08-09 21:16:19 · 1030 阅读 · 2 评论 -
const 剖析
const 限定符const 作用const的使用定义常量 const修饰常量,以下两种定义形式本质上一样:const修饰的类型为TYPE的变量value是不变的; TYPE const ValueName = value; const TYPE ValueName = value; - 将const 改为外部链接,作用原创 2017-06-16 16:23:51 · 195 阅读 · 0 评论 -
牛客网错题总结
对于std::vector::at总是做边界检查,而对于std::vector::operator[]则不会做边界检查;clone()可以将父进程资源有选择的复制给子进程,而没有复制的数据结构则通过指针的复制让子进程共享,具体要复制哪些资源给子进程,由参数列表中的clone_flags来决定,其返回的是子进程的pid;p = NULL 和 p = 0 , p = ‘\0’是等价的;80X86是原创 2017-06-03 11:08:45 · 322 阅读 · 0 评论 -
C++ 类型转换运算符
C++相比于C是一门面向对象的语言,面向对象最大的特点之一就是具有“多态性(Polymorphism)”。要想很好的使用多态性,就免不了要使用指针和引用,也免不了会碰到转换的问题。C++提供了四个转换运算符:const_cast (expression)static_cast (expression)reinterpret_cast (expression)dynamic_cast原创 2017-06-18 15:51:46 · 972 阅读 · 0 评论 -
C++ 对象的内存布局
对象的影响因素简而言之,一个类可能会有如下的影响因素:成员变量虚函数(产生虚函数表)单一继承(只继承于一个类)多重继承(继承多个类)重复继承(继承的多个父类中其父类有相同的超类)虚拟继承(使用virtual 方式的继承,为了保证继承后的父类的内存布局只会存在一份)上述通常是C++ 这门语言在语义方面对对象内部的影响因素,当然,还会有编译器的影响(比如优化),还有字节对齐的影响, 在这里原创 2017-06-18 22:38:39 · 224 阅读 · 0 评论 -
C++知识点总结
对于std::vector::at总是做边界检查,而对于std::vector::operator[]则不会做边界检查;clone()可以将父进程资源有选择的复制给子进程,而没有复制的数据结构则通过指针的复制让子进程共享,具体要复制哪些资源给子进程,由参数列表中的clone_flags来决定,其返回的是子进程的pid。p = NULL 和 p = 0 , p = ‘\0’是等价的。原创 2017-06-02 18:22:11 · 300 阅读 · 0 评论 -
C++ primer
main函数的返回值main函数的返回值用于说明程序的退出状态,如果返回0,则代表程序正常退出,否则代表程序异常退出。 任何一个C++程序都必须定义一个main函数,它的返回类型总是int类型。这个函数由操作系统来调用,在main函数执行完以后,程序也就终止了。main也可以使用return 向操作系统返回一个值,使用操作系统的命令可以检测到该值。一般约定在main返回0时,表示程序运行过程中没有原创 2017-06-16 16:16:56 · 291 阅读 · 0 评论 -
C++多态性
本文参考浅谈C++多态性多态性可以简单地概括为“一个接口,多种方法”,程序在运行时才决定调用的函数,它是面向对象编程领域的核心概念。多态(polymorphism),字面意思多种形状。C++多态性是通过虚函数来实现的,虚函数允许子类重新定义成员函数,而子类重新定义父类的做法称为覆盖(override),或者称为重写。(这里我觉得要补充,重写的话可以有两种,直接重写成员函数和重写虚函数,只有重写了虚函原创 2017-06-20 23:07:32 · 191 阅读 · 0 评论 -
拷贝、赋值和销毁
拷贝(1):拷贝构造函数如果一个构造函数的第一个参数是自身类类型的引用,且任何额外参数都有默认值,则此构造函数为拷贝构造函数;拷贝初始化不仅在我们用 = 定义变量时发生,以下情况也会发生:将一个对象作为实参传递给一个非引用类型的形参;从一个返回类型为非引用类型的函数返回一个对象;用花括号列表初始化一个数组中的元素或一个聚合类的成员;拷贝构造函数用来初始化非引用类型的参数,解释了为什么拷贝构原创 2017-06-21 11:29:18 · 336 阅读 · 0 评论 -
C++面试题总结
为什么C++的member function template不能是虚的?问题的意思是:为什么在C++里面,一个类的成员函数不能既是template优势virtual,比如,下面的代码是不合法的:class Animal{public: template<typename T> virtual void make_sound(){ //... } };原创 2017-06-13 15:04:39 · 851 阅读 · 0 评论 -
C++中的单例模式
单例模式也称为单件模式、单子模式,可能是使用最广泛的设计模式。其意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。有很多地方需要这样的功能模块,如系统的日志输出,GUI应用必须是单鼠标,MODEM的联接需要一条且只需要一条电话线,操作系统只能有一个窗口管理器,一台PC连一个键盘。单例模式有许多种实现方法,在C++中,甚至可以直接用一个全局变量做到这一点,但这样的代原创 2017-06-21 15:27:21 · 190 阅读 · 0 评论 -
内联函数总结
定义它们看起来像函数,运作起来像函数,比宏(macro)要好得多,使用时还不需要承担函数调用的负担。当内联一个函数时,编译器可以对函数体执行特定环境下的优化工作,这样的优化对“正常”的函数调用时不可能的。规则inline关键字必须和函数体定义放在一起才可以实现内联,仅仅将inline放在函数声明之前不起任何作用。inline是一个用于实现的关键字而不是一个用于声明的关键字。对于类方法,定义在类内部的原创 2017-06-13 21:14:41 · 358 阅读 · 0 评论 -
C/C++内存泄漏及检测
本文参考内存泄漏检测 “该死系统存在内存泄漏问题”,项目中由于各方面因素,总会有人抱怨存在内存泄漏,系统长时间运行之后,可用内存越来越少,甚至导致了某些服务失败。内存泄漏是最难发现的常见错误之一,因为除非用完内存或调用malloc失败,否则都不会导致任何问题。实际上,使用C/C++这类没有垃圾回收机制的语言时,你很多时间都花在处理如何正确释放内存上,如果内存运行时间足够长,如后台进程运行在服务器上原创 2017-07-31 17:02:48 · 370 阅读 · 0 评论 -
如何定义一个只能在堆上(栈上)生成对象的类?
在C++中,类的对象建立分为两种:一种是静态建立,如A a;另一种是动态建立,如A* ptr=new A;这两种方式是有区别的。静态建立一个类对象,是由编译器为对象在栈空间分配内存,通过直接移动栈顶指针,挪出适当的空间,然后在这片内存空间上调用构造函数形成一个栈对象。使用这种方法,直接调用类的构造函数。动态建立类对象,是使用new 运算符将对象建立在堆空间中。这个过程分为两步:执行opera原创 2017-08-08 17:53:22 · 352 阅读 · 0 评论 -
100层楼2个鸡蛋,如何得知鸡蛋能承受几层的撞击
有一栋楼共100层,一个鸡蛋从第N层及以上的楼层落下来会摔破, 在第N层以下的楼层落下不会摔破。给你2个鸡蛋,设计方案找出N,并且保证在最坏情况下, 最小化鸡蛋下落的次数。 我们先假设最坏情况下,鸡蛋下落次数为x,即我们为了找出N,一共用鸡蛋做了x次试验,那么,我们第一次应该从哪层楼往下扔鸡蛋呢?先让我们假设第一次是在第y层楼扔的鸡蛋,如果第一个鸡蛋第一次扔的时候就摔碎了,我们就剩下一个鸡蛋,要用它原创 2017-08-09 17:57:05 · 556 阅读 · 0 评论 -
C++面试知识点
strcpy函数实现char* strcpy(char* dest, const char* src){ assert((dest != NULL) && (src != NULL)); //检查指针的有效性 char* res = dest; while((*dest++ = *src++) != '\0'); return res; //返回res的原始值使函数能够支持链式表原创 2017-09-02 21:12:19 · 353 阅读 · 0 评论