c/c++资源收集

参考手册

ClassFoo / C++ 参考手册

基本概念

陈皓 - 深入理解C语言
陈皓 - 64位平台C/C++开发注意事项
C和C++中struct使用的区别
new 和 malloc 的区别
补:
运算符/库函数、初始化、构造/析构函数、自动计算大小、返回指定类型指针。
C 中 static 的常见作用
sizeof与strlen的区别与联系
const static与static const的使用
const常量与define宏定义的区别
const的实现原理
补:
在C里,const常量总是会分配内存,位于只读数据段。
在C++中,对于基本类型的常量,编译器并不为其分配存储空间,而是放到符号表,在编译器里进行语法分析的时候,将常量表达式计算求值,并用求得的值来替换表达式,这就是C++的常量折叠。而一旦对const常量使用extern外部引用,或者&解地址等操作时,就会迫使C++编译器给这个const变量分配内存,编译器会重新在内存中创建一个它的拷贝,通过地址访问到的就是这个拷贝而非原始的符号常量;否则就是一个编译时的符号,不占用内存。
详解C中volatile关键字

指针

NULL指针、零指针、野指针
std::auto_ptr智能指针
C++ 智能指针详解
函数指针 + 数组指针
多维指针

内存布局

内存管理内幕
补:
几个基本的内存管理策略:malloc、引用计数、内存池、垃圾回收。
Glibc 内存管理
补:
关注要点:1、chunk组织方式;2、空闲chunk容器种类;3、内存分配步骤;4、内存回收步骤;5、mmap分配阈值动态调整时机;6、fast bins合并时机 ;7、避免glibc内存暴增方法。
长生命周期的大内存应使用mmap分配,如果使用sbrk分配,该内存块长期被占用会导致后续短生命周期内存释放后无法归还给操作系统。但是mmap效率低,mmap分配阈值动态调整正是为了使大于128K的短生命周期大内存尽量不会使用mmap分配。
C/C++内存管理详解
补:
堆和栈的区别:管理方式、空间大小、是否造成内存碎片、分配方式、分配效率、生长方式。
野指针的成因:初始化时没有设为NULL或指向合法的内存区、释放时没有设为NULL、操作时超出了变量作用域。
C/C++ 结构体字节对齐详解
题 - c++ 类的内存布局
陈皓 - C++ 虚函数表解析
陈皓 - C++ 对象的内存布局
补:
1、多重虚拟继承时,子类独有的虚函数会放到第一个父类的虚函数表;g++实验证明,子类重写的其他父类的虚函数会放到第一个父类的虚函数表,但子类重写的第一个父类的虚函数不会放到其他父类的虚函数表(vc++标准可能不一样)。
2、多重继承且父类都虚拟继承同一个爷爷类时,构建顺序是【爷爷类->父类1->父类2->子类】,实例顺序是【父类1->父类2->子类->爷爷类】。
3、虚拟继承与虚函数之间没有任何绝对联系。虚函数是为了解决多态的问题,虚拟继承是为了解决重复继承中多个间接父类的问题。
4、g++实验证明,多重继承且父类都虚拟继承同一个爷爷类时,如果没有涉及虚函数,父类都有对应的虚拟表(父类实例的第一个位置存储表的地址),存储的是虚继承的内容,爷爷类没有对应的虚拟表;如果子类、父类、爷爷类都定义了对应的虚拟函数,则子类实例中父类和爷爷类都会有对应的虚拟表(虚拟表将优先存储虚拟函数内容,再存储虚继承的内容,但并不是每个虚拟表都这样,每个虚拟表如何处理虚继承的内容目前还不清晰),但“子类本身”没有虚拟表(子类独有的虚函数会放到第一个父类的虚拟表)。
多重继承和虚继承的内存布局
父类virtual虚构函数(其他成员函数同)
补:
多继承的情况下,首先按照继承顺序调用类的构造函数,再调用子类的构造函数。
delete某个基类指针时,只看指针的声明类型的类中是否将析构函数声明为虚函数,如果是则成功按照调用构造函数的相反顺序调用析构函数(跟该类被继承的顺序没关系,且其他被继承类有无设置虚析构函数也没关系),如果不是则只调用该基类的析构函数。
delete基类指针时,始终按照调用构造函数的相反顺序调用析构函数。

数组

C/C++中的0长数组(柔性数组)
陈皓 - C语言结构体里的成员数组和指针
补:
使用0长数组而不是指针,是为了一次malloc就给一个结构体内的数据分配一个连续的内存,一次free就可以把所有的内存也给释放掉。
对于char s[0]来说,汇编代码用了lea指令,lea 0x04(%rax), %rdx
对于char*s来说,汇编代码用了mov指令,mov 0x04(%rax), %rdx
lea全称load effective address,是把地址放进去,而mov则是把地址里的内容放进去。访问成员数组名其实得到的是数组的相对地址,而访问成员指针其实是相对地址里的内容。

c++

C++异常机制的实现方式和开销分析
区分 浅/深拷贝操作 和 赋值操作
通过初始化列表来初始化的成员变量(引用,const和没有默认构造函数的成员对象)
补:
const、引用、无默认构造函数的成员变量(调用拷贝构造函数初始化)
c++类中成员变量的初始化总结
c++中临时变量不能作为非const的引用参数
C++公有继承、保护继承、私有继承的区别
友元函数
C++继承中重载、重写、重定义的区别
补:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1 成员函数重载特征(c++类不能同时存在函数名和参数一样的静态函数和非静态函数):
a 相同的范围(在同一个类中)
b 函数名字相同
c 参数不同
2 重写(覆盖)是指派生类函数覆盖基类函数,特征是:
a 不同的范围,分别位于基类和派生类中
b 函数的名字相同
c 参数相同
d 基类函数必须有virtual关键字
3 重定义(隐藏)是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
a 如果派生类的函数和基类的函数同名,但是参数不同,但是基类函数没有vitual关键字,此时,基类的函数被隐藏。
b 如果派生类的函数和基类的函数同名,但是参数不同,基类函数有vitual关键字,此时,基类的函数被隐藏。
c 如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有vitual关键字,此时,基类的函数被隐藏。
d 可以在子类成员函数中通过[父类::]的方式调用被隐藏的函数,但是无法通过子类类型的子类实例调用到父类被隐藏的方法。

c++11

lambda 表达式解析
C++11新特性学习笔记
C++11中的右值引用

优化

Valgrind使用简介

预处理

C 语言预处理命令总结大全

函数区别

memmove 和 memcpy 的区别
补:
经实验,当dst在src后面且dst在src范围内时:
memmove和memcpy都能够正确复制,类似于实现时先复制到临时数组中;
strcpy无法确保正确复制,而且strcpy复制的个数算上了结束符(猜想strcpy的实现是先计算复制个数,算上结束符,但是没有先复制出数据);
memccpy也无法确保正确复制,在复制过程中会覆盖原有内容,如果一直没有遇到匹配字符,将复制原先整个src的长度;如果遇到匹配字符,结束复制,匹配字符会被复制(猜想memccpy的实现是先计算复制个数,不算上结束符)。
strcat会直接走到dst末尾,然后连接上原先整个src的长度的数据(猜想strcat的实现是先计算复制个数,不算上结束符)。
标准C中字符串分割方法
strcpy和strncpy用法和区别

STL

STL的线程安全解决方案

混合编程

C和C++混合编程

显示 Gitment 评论