
C++
zidian666
这个作者很懒,什么都没留下…
展开
-
别再用ftime!!有大坑!!
某个业务执行时需要写日志,但调用完日志后(日志中有调用ftime),调用处附近的变量值莫名地被修改了。换成C++的std::chrono就没这b问题了。gdb显示问题出在ftime()上。用gdb的watch定位到日志上。其次,它会污染内存。原创 2023-05-16 16:10:12 · 835 阅读 · 0 评论 -
shared_ptr的一个使用不慎
pop出智能指针之后,在下一次pop时阻塞,导致上次pop的智能指针引用计数未即时归零。本来等指针指针析构时调用对象的析构函数,发现偶尔会不调用,找了一下午才发现这问题。后面加了两个if后问题解决。原创 2022-12-13 17:57:28 · 111 阅读 · 0 评论 -
linux 无缓冲立即读取输入的字符
原理就是从/dev/tty文件读取。/dev/tty存放你终端的信息。C++写法C写法,有坑,每读取一个字符都会打开一次该文件,超过一定数量会不被linux允许。此代码来自网络。可以将tty声明为静态,或者每次打开后都关闭该文件原创 2022-12-06 16:28:43 · 426 阅读 · 0 评论 -
修改一个SQL控制台的心得
现在已经基本做完了,所以没法改动了。如果一开始能想到这点,会方便很多。 为输入的每个字符生成坐标,目前最难做的上下左右功能也会变得简单。 某函数ioctl()可以获取屏幕能容纳的行数和列数。 用两个头对头(入口对入口,也即出口对出口)的栈实现(并不唯一)3.使用无阻塞输入 做这个东西要么输入时不用缓冲区,要么用键盘监控。 但是不知道在用终端ssh连接centos时能不能监听键盘事件。原创 2022-12-05 18:34:38 · 320 阅读 · 0 评论 -
libevent-bufferevent遇到的坑
1. 多线程操作段错误2. 对evbuffer加锁后还是段错3. 在2情况下创建的buffeevent为nullptr4. 建议加入水位线控制原创 2022-11-30 11:25:40 · 353 阅读 · 0 评论 -
自定义<set><map>的hash函数时遇到的问题
Hash和Equal为对象时, 其operator()后应加上const。原创 2022-10-21 12:01:50 · 130 阅读 · 0 评论 -
测试std::unordered_map的hash冲突
std::unordered_map的实现为hash表,所以hash值范围越小,越容易出现冲突,效率越低。m 查找 0.004000 0.018000 0.146000。m2 查找 0.004000 0.004000 0.004000。m用的是自定义的hash函数hash值只有0和1,m2用默认hash函数。n为数据量,times为测试次数,下面结果取最后一次测试结果。n为100,1000,10000时。原创 2022-10-09 17:14:04 · 497 阅读 · 0 评论 -
函数中有多处返回,多次写释放申请的内存太麻烦?
代码中可能会遇到这种情况,函数中申请了内存,函数中进行多次判断,根据不同情况返回不同的值,每个return前都需要释放申请的内存。解决方式:用unique_ptr代管申请的内存,析构时自动释放。原创 2022-08-23 11:49:32 · 151 阅读 · 0 评论 -
当编译链接时error:undefined reference to xxx
C++在编译期间不能决定模板参数的类型,如果在编译时有实例调用了类模板函数,则未定义。与这个情况相似:不完整类型不能用于定义该类型的实例,只能用于定义该类型的指针实例。在我的代码中,问题出在模板类函数的声明和定义分别放在.h和.cpp中。是的,没错,这是问题所在。链接时决定模板参数类型。...原创 2022-08-18 17:07:14 · 445 阅读 · 0 评论 -
error:type/value mismatch at ... ::iterator
修改方式:在 std::list前加类型声明typename。加上typename,让编译器知道你是在声明一个类型而不是访问静态成员。原因:有没有觉得class::xxx的写法像是在访问类里的静态成员。iterator是stl类的嵌套类。错误在编译以下代码时出现。...原创 2022-08-18 15:03:07 · 238 阅读 · 0 评论 -
C++ std::map用迭代器遍历删除遇到的坑
需求是这样的 表面上看没什么问题,迭代器也在删除后做了赋值,感觉自己避开了坑,很开心。然而当map只有一个元素的时候,在erase(it)后,it的值是map.begin(),此时map.begin()==map.end()。for结束一次循环,++it,那么it = map.begin() + 1,不再等于map.end(),循环继续,并且不会再停下来。在这个项目中,锁也没有释放,就会让后面的线程全部堵在自旋锁上,cpu占用 += 100%。题外话可能会有人吐槽这种遍历复杂度太高N^3。准备增原创 2022-07-08 10:41:27 · 2761 阅读 · 0 评论 -
将vector<string>写入文件,但文件大小与期望不一致
打算用 vector 装 1024 * 1024 * 64 个长度为 16 的 string,共计1GB大小,随机生成内容,写成文件,作为压缩测试的文件。但是用以下语句,写出来的文件大小每次都不一样。ofstream.write((char *)vector.data(), 16 * vector.size());想了很久才悟到,vector 上的对象是在内存上是连续的,但指的是 string 对象。string 的内容未必在(应该完全不在)vector 上。vector 上的连续空原创 2022-03-03 10:33:07 · 329 阅读 · 0 评论 -
C++ primer阅读笔记 继承
若基类中声明了纯虚函数,继承类必须重写该函数。virtual void fun1() = 0;含有纯虚函数的基类是抽象基类,它定义了类的接口,但将接口的实现交给继承类。派生类的成员和友元只能通过派生类访问基类的受保护对象。class Base{protected: int a;};class Inherite: public Base{ friend void f1(Base &b){ //编译器将报错 b.a = 0; }原创 2022-02-21 16:51:28 · 229 阅读 · 0 评论 -
分布式日志聚集系统开发总结
项目功能主要功能:接收来自多个节点的日志,按节点名存入文件。分析功能:设定多个Tag,将日志与Tag匹配。最终可以让用户指定Tag,将所有匹配日志存入指定文件。对外接口类LogService主要对外接口。启动后持续运行,接收节点日志,交给Handler类处理。用户可以设定并行线程数。TagManager管理Tag。单例。Analyst分析数据。生成Tag文件。内部实现类FileWriter打开文件写入。Han...原创 2022-02-21 09:51:46 · 499 阅读 · 0 评论 -
C++开发经验之谈1
返回类成员引用时注意是否有修改,导致原引用可能出错某些成员是否可以作为处理它的类的成员,而不是以传参的形式将成员传给处理它的类不能为了效率滥用引用树查找虽然快,但多次查找不如用迭代器进行一次查找,后面就用迭代器某些时候,取指针所指值拷贝不如直接拷贝指针用{}很轻易地限制unique_ptr的作用域。stl.reserve()预留空间但不构建对象,stl.resize()分配空间且构建对象。while(flag)可能被编译器优化共享队列front(); pop.原创 2022-02-18 16:54:44 · 182 阅读 · 0 评论 -
Linux内存管理初探
总结自网络资料,做了部分验证。——————————————————————————————————————————Linux为进程提供4GB的虚拟内存(如果不了解虚拟内存,就当成物理内存)。如果把内存想象成从地址低到高的顺序表,竖着放,地址高在上,低在下。(更严谨一点,小端模式下)则从上到下,从高到低,内存中储存的内容依次为:内核栈 ↓MMAP ↓堆 ↑BSSdata代码段操作系统保留区域1、内核大小1GB。2、栈上面是内核,不可访问,原创 2022-02-16 18:13:12 · 398 阅读 · 0 评论 -
C++虚函数表
在对象创建时,编译器自动地在对象的起始地址处创建一个虚函数表,表里是类的虚函数地址。如果子类将其继承但不重载虚函数,子类对象的起始地址也会存父类的虚函数,若有重载,将虚函数替换为对应的子类重载函数地址。...原创 2022-02-16 13:41:52 · 434 阅读 · 0 评论 -
C++内存对齐
class A{ int a; char b;};class B : A{ char c;};int main(){ printf("%d %d\n", sizeof(A), sizeof(B));}输出 8 8此例说明两个问题:1、内存对齐2、子类数据在基类数据之后原创 2022-02-16 11:52:51 · 393 阅读 · 0 评论 -
queue线程安全
queue非线程安全大佬封装成线程安全的,接口与原<queue>一致,但无法拷贝(锁)#pragma once#include <queue>#include <mutex>#include <condition_variable>template <typename T>class SharedQueue{public: SharedQueue(); ~SharedQueue(); T &am原创 2022-02-08 17:32:09 · 1656 阅读 · 0 评论 -
fputs线程安全
fputs()是线程安全的。fputs_unlocked()是非线程安全的,在多线程中使用需要像使用锁(mutex)一样,使用flockfile() 或 ftrylockfile() 函数后才能安全地在多线程中使用。来自IBM的文档原创 2022-02-08 14:48:35 · 333 阅读 · 0 评论 -
C++ 重载前置和后置++/--运算符
要想同时定义前置和后置运算符,必须首先解决一个问题,即普通的重载形式无法区分这两种情况。前置和后置版本使用的是同一个符号,意味着其重载版本所用的名字将是相同的,并且运算对象的数量和类型也相同。为了解决这个问题,后置版本接受一个额外的(不被使用) int类型的形参。当我们使用后置运算符时,编译器为这个形参提供一一个值为0的实参。尽管从语法上来说后置函数可以使用这个额外的形参,但是在实际过程中通常不会这么做。这个形参的唯一作用 就是区分前置版本和后置版本的函数,而不是真的要在实现后置版本时参与运算。...原创 2022-01-26 09:17:20 · 592 阅读 · 0 评论 -
C++primer阅读笔记 13章 拷贝控制
一个类必须拥有拷贝构造、移动构造、拷贝赋值、移动赋值、析构函数。如果它们未被显式定义,编译器将会自动合成它们。默认的拷贝构造函数会将源对象的成员依次复制到新对象中,如果成员中有类类型,还会调用它们的拷贝构造函数。拷贝初始化通常调用拷贝构造函数完成,有时也会调用移动构造函数。拷贝初始化不仅在我们定义类对象时发生,也会在传递非引用参数、返回非引用对象、初始化列表时发生。拷贝构造函数的参数必须为引用类型。如果不是引用类型,当构造发生时,形参必须拷贝实参,由此调用拷贝构造函数,为了调用拷贝构造函数,又必原创 2022-01-24 15:10:45 · 419 阅读 · 0 评论 -
C++ primer阅读笔记 泛型算法
find函数底层实现是使用类的 == 重载一一对比,这意味着类必须支持 == 。find(begin, end, value),若未查找到value,返回end。vector<int> v{1,2,3,4,5};cout << accumulate(v.begin(), v.end(), 100);cout << accumulate(v.begin(), v.end(), 100, [] (int &a, int &b) { re原创 2022-01-24 11:08:38 · 564 阅读 · 0 评论 -
C++primer笔记 流和容器
“ 由于不能拷贝IO对象,因此我们也不能将形参或返回类型设置为流类型。进行I0操作的函数通常以引用方式传递和返回流。读写一个IO对象会改变其状态,因此传递和返回的引用不能是const的。”whlie(cin >> str) do something;cin >> str返回流的状态,只要流未出错,cin >> str始终为真。difference_type对于不能相减(一般是非随机访问)的迭代器还是有意义的...原创 2022-01-24 10:11:35 · 602 阅读 · 0 评论 -
C++primer阅读笔记 第7章类
“ 在一些简单的应用程序中,类的用户和类的设计者常常是同一个人。尽管如此,还是最好把角色区分开来。当我们设计类的接口时,应该考虑如何才能使得类易于使用;而当我们使用类时,不应该顾及类的实现机理。”const(常量)对象只能访问const成员函数,和全部成员(如果public),但只读。一般(变量)对象可以访问全部成员和成员函数,但对const成员只读。const成员函数只能访问const成员函数。普通成员函数可以访问全部成员函数。简单理解:const对象是常量,当然只读。一般对象..原创 2022-01-24 09:34:34 · 431 阅读 · 0 评论 -
C++11primerP1第6章函数
内联函数,inline声明,直接在调用的地方展开编译,省去调用函数的开销。通常用于,体积小,调用频繁,逻辑简单的函数。constexpr声明表达式或函数为常量,让编译器能在运行前计算出表达式和函数的返回值。assert()括号内的表达式,如果为真无事发生,如果为假程序异常。下面情况中,fun(a)调用第一个函数,fun(b)调用第二个函数。a是int不能绑定到const&,b和第二个函数精确匹配。void fun(int& a);void fun(cons原创 2022-01-21 16:14:36 · 305 阅读 · 0 评论 -
C++primer阅读笔记-第四章:表达式
如果一条表达式中有size()函数,就不要再用int了,避免unsigned和int混用for(size_t i = 0; i < vector.size(); ++i);C++兼容C的头文件,最好按标准用#include <cname>的方式引用#include <cstdio>逻辑与运算符&&,在前一个条件为真时才会检查后一个条件。用数组初始化vector时,可以用std::begin()和end()取数组。int arr[]原创 2022-01-21 14:27:45 · 519 阅读 · 0 评论 -
C++11 primer阅读笔记 第二章
同一类型变量在不同机器上的bits可能不同,好的程序应该知道怎么处理同类型变量在不同机器上拥有不同的尺寸。字符型有三种类型char / signed char / unsigned char,实际表现形式是后两者,声明char型,会由编译器决定具体为后两者之中的哪一种。不要用char型做运算,因为不确定它是否有符号。如果要较小的整型,可以用signed char 和unsigned char.不要把负值赋给unsigned,实际上,最好不要把有符号赋值给无符号。也不要使两个无符号数运算结果为..原创 2022-01-21 11:14:23 · 210 阅读 · 0 评论 -
C++STL之vecot、list、deque的排序插入访问效率
低数据量的参考价值不高,其余数据仅供参考,测试代码在末尾排序第一次测试 第二次测试 STL类型 数据量 时间 STL类型 数据量 时间 vector [10] 0.002000 ms vector [10] 0.001200 ms deque [10] 0.001000 ms deque [10] 0.001200 ms list [10] 0.006100 m...原创 2022-01-20 15:31:39 · 734 阅读 · 0 评论 -
C++ tuple
声明及定义tuple<int, float, double, char*> tup;赋值,get返回的是引用,既能取值也能赋值get的参数只能用常量和宏,不能用变量 get<0>(tup) = 1; get<1>(tup) = 1.3; get<2>(tup) = 1.567; get<3>(tup) = new char[10];用tie关键字取值,值传入a,b,c,d int原创 2022-01-19 15:11:31 · 567 阅读 · 0 评论 -
C++STL之memory
allocator,分配内存但不进行任何初始化,很少用shared_ptr 共享指针,初始化后同指针一样指向一个对象,成员函数use_count() 表示有多少共享指针指向对象,每当shared_ptr被赋值、拷贝的时候,use_count()加1,一个共享指针不再指向对象时,use_count减1。以这种方式构造的,指向同一个对象的指针,use_count是共享的。不要使用同一个对象初始化多个共享指针。一个对象只能初始化一个共享指针。其成员函数get()可返回对象类型的指针,也不要用这个指针初始化原创 2022-01-19 14:17:40 · 441 阅读 · 0 评论 -
C++ STL之 algorithm
Algorithms library (Algorithm) - C++ 中文开发手册 - 开发者手册 - 云+社区 - 腾讯云函数意如其名,一般会有带谓语参数的重载版本,可以手写操作规则。原创 2022-01-19 10:57:34 · 226 阅读 · 0 评论 -
C++ stl学习随笔: const int 实参和int &&形参
学习<algorithm>时测试any_of()int main(){ map<int, float> m{{1,2},{3,4},{5,6},{7,8}}, m1{{1,2}, {3,4}, {5,6}}; cout << any_of(m.begin(), m.end(), [] ( pair<int, float> &i) { return i.first > 1; } ; }编译报错:error: ca原创 2022-01-19 10:30:36 · 678 阅读 · 0 评论 -
C++ STL 之set
不要使用过期的iteratorset,集合其中所有元素都是唯一的,set中的元素是有序的。定义set时 set<int, less<int>>表示升序,set<int, greater<int>>可声明降序。set的数据结构为红黑树,不打算讲,因为笔者也不是很明白。插入和查找的时间复杂度为log2,相当于数据量翻倍,时间+1。equal_range(n),返回一个pair,<第一个可插入n的位置,最后一个可插入n的位置>e原创 2022-01-18 17:14:39 · 403 阅读 · 0 评论 -
C++STL之list
list,链表基本实现方式为一个struct包含数据和指针,每个指针指向下一个节点。STL中的list为双向链表,即struct中包含一个数据和两个指针,分别指向前一个节点和后一个节点。很显然,这样的结构会使list的插入删除操作非常灵活,插入和删除都只会影响最近的两个节点,而且访问头部和尾部都很方便。缺点是不能随机访问,不能像vector的at()和 [ ] ,每个数据都需要依次访问。其迭代器未重载+,-,+=,-=,只重载了++和--,即迭代器只能自增1和自减1.remove(n原创 2022-01-18 16:22:20 · 617 阅读 · 0 评论 -
C++ STL之Deque
<deque>的关键在于其内部的实现,存储管理机制。deque的内存时分段连续的,连续是假象。虽然可以像访问vector和数组一样用 [ ] 访问每一个元素,但花费的代价比较大。(假设deque中的元素为int),deque用一个vector保存一组int**,每个int**指向一个int*,int*就是数组的起始地址。所以deque的实质就是,vector中的每个元素指向一个数组,数组中元素就是deque的元素。deque能像vector一样访问元素,功劳在itearator身原创 2022-01-18 14:40:05 · 278 阅读 · 0 评论 -
C++ STL之 vector
vector实现原理是数组,其元素在内存上是连续的。学会vector的关键在于区别size()和capacity()。其成员函数vector.size()表示vector中实际元素的数量。vector的长度是不确定的,当往vector添加元素时,如果vector后的连续空间不足以插入元素,vector会重新申请一段更长的空间。vector.capacity()表示在不需要重新分配内存的情况下,vector能容纳的最多元素个数。若需重新分配空间,新的vector.capacity()会变为原创 2022-01-17 15:18:46 · 271 阅读 · 0 评论 -
C++ Primer 中文版 阅读笔记
笔记始于章节11.3.31、multimap和multiset中,若有多个同一键值的元素,这些元素相邻储存2、lower_bound若未查找到seach_item,返回第一个大于seach_item元素的迭代器3、find函数的参数使用反向迭代器,可实现从后向前查找4、equal_range查找关键字返回pair,pair.first和second指向第一个和最后一个(关键字位置)的迭代器5、在一个升序的容器里,如果所有元素都大于你要找的,则upp和low都返回begin。都小于则返回e原创 2022-01-13 14:31:13 · 185 阅读 · 0 评论 -
OpenCV+C++运行时去除控制台
一、// 在代码中加入#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" ) 二、将图片所指的位置改为 “窗口”,但这样可能出现报错“找不到程序入口”...原创 2018-10-03 14:25:37 · 560 阅读 · 0 评论 -
Qt creator4.7.1 + OpenCV3.4.3配置(附百度网盘下载链接)
(注意对应路径),配置:在.pro文件中加入:INCLUDEPATH += F:\OpenCV\opencv\build\include\ F:\OpenCV\opencv\build\include\opencv\ F:\OpenCV\opencv\build\include\opencv2LIBS += -LF:\OpenC...原创 2018-10-03 16:15:59 · 3443 阅读 · 2 评论