0%

C++ 中 auto-ptr 特性和源码解析

简介

std::auto_ptr 包含在头文件 < memory > 中,它被用来实现对动态分配对象的自动释放。如:

1
2
3
4
void test(){
int*p=new int(0);
auto_ptr<int> ap(p);
}

这段代码不会造成内存泄漏,因为在ap这个对象结束生命周期时,其包含的p会被自动释放。这几乎已经是auto_ptr的全部作用了,但是还有一些小秘密,下面结合它的代码看看他的实现,挖挖它的内涵。

阅读全文 »

位域的字节序

问题的起源

今天阅读到ip头结构体,看到前面两个字段用到了宏,可以看到这两个字段在大小端(大/小字节序)情况下的顺序是不同的。
于是有一个疑问,为什么其他字段可以不管大小端,唯独这两个字段要关注大小端。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//IP头部,总长度20字节   
typedef struct _ip_hdr
{
#if LITTLE_ENDIAN
unsigned char ihl:4; //首部长度
unsigned char version:4, //版本
#else
unsigned char version:4, //版本
unsigned char ihl:4; //首部长度
#endif
unsigned char tos; //服务类型
unsigned short tot_len; //总长度
unsigned short id; //标志
unsigned short frag_off; //分片偏移
unsigned char ttl; //生存时间
unsigned char protocol; //协议
unsigned short chk_sum; //检验和
struct in_addr srcaddr; //源IP地址
struct in_addr dstaddr; //目的IP地址
}ip_hdr;
阅读全文 »

condition_variable

简介

在头文件< condition_variable >中,顾名思义是一个条件变量,主要功能是阻塞线程直到另一个线程把你唤醒。

条件两个字看起来似乎是指,在另一个线程中满足了条件,才把你唤醒;然而如果仅仅如此的话信号量就能满足要求了。

所以条件二字更体现在你需要满足更具体的”条件”才能被唤醒。

来看一个简单的例子:

阅读全文 »

ODR-(One Definition Rule) 下的奇淫异技

一行输出引起的..故事

首先看这个终端的输出结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@localhost xxxx]# g++ -o binary binary.cpp libb.a liba.a
[root@localhost xxxx]# ./binary
1
1
[root@localhost xxxx]# g++ -o binary binary.cpp liba.a libb.a
[root@localhost xxxx]# ./binary
2
2
[root@localhost xxxx]# cat binary.cpp
#include <iostream>

extern int fna();
extern int fnb();

int main(){
std::cout << fna() << std::endl;
std::cout << fnb() << std::endl;

}

可以看到我们通过改变两个库的链接顺序,改变了两个函数的返回值。how?
如果你对这个结果并没什么兴趣,你也许对下面的内容也不感兴趣。但是如果你挺有兴趣的话我们就来一起看看。

阅读全文 »

shared_ptr 之shared_from_this

简介

shared_ptr包含在头文件< memory >中,它被用于共享某个指针的场景下智能管理指针的生命周期。
怎么个智能法:当没人再用这个指针的时候释放指针,看起来很像GC对不对,不过比GC及时,shared_ptr是一旦没人用了立即释放,而GC是会等等看,看情况再来释放。

首先来看一个典型的用法:

1
2
3
4
5
void simple(){
std::shared_ptr<int> sp(new int(0));
std::shared_ptr<int> sp2 = sp;
}

可以看出两点,一个是shared_ptr是可以赋值给别的变量的,不需要像unique_ptr那样通过move来赋值,因为shared_ptr不是独占指针而是共享,所以赋值是很平常的操作。 二是你不需要去手动释放该指针,new出来的变量会在最后一个相关联的shared_ptr消失时被释放,也就是在simple函数退出时,sp和sp2相继被销毁,于是new出来的变量也紧接着被释放,没有后顾之忧。

再来看一个错误的用法:

1
2
3
4
5
6
void fail(){
int * p=new int(0);
std::shared_ptr<int> sp(p);
std::shared_ptr<int> sp2(p);
}

阅读全文 »

C++ 中 unique-ptr 特性和源码解析

简介

std::unique_ptr 包含在头文件< memory > 中,它被用来实现对动态分配对象的自动释放。

这是一个在auto_ptr基础上发展并取代auto_ptr的类,所以它具有auto_ptr的自动释放特性以及独占控制权的特性,可以参考我之前关于auto_ptr的文章。最简单的用法如下:

1
2
3
4
void test(){
int*p=new int(0);
unique_ptr<int> ap(p);
}

那么为什么unique_ptr要诞生来取代auto_ptr呢,首先为什么不是修改auto_ptr而要另起炉灶呢,这主要是不希望用一种静默的方式来修改它,从而使得你忽略了auto_ptr已经不是当初的auto_ptr了,以此来避免隐含bug而你却没意识到。

另一个方面是unique_ptr比auto_ptr好在哪里, unique_ptr的出现是为了解决auto_ptr的两个问题,一个是静默的控制权转移问题,一个是不支持数组问题。

阅读全文 »