C++编译与底层相关知识点复习笔记

一、C++源文件从文本到可执行文件经历的过程?
预处理阶段:将头文件宏定义进行分析和替换,生成预编译文件
编译阶段:将预编译文件转换成特定汇编代码,生成汇编文件
汇编阶段:将编译阶段生成的汇编文件转化成机器码,生成可重定位目标文件
链接阶段:将多个目标文件及所需要的库连接成最终的可执行目标文件

二、include头文件的顺序?
对于include的头文件来说,如果在文件a.h中声明一个在文件b.h中定义的变量,而不引用b.h。那么要在a.c文件中引用b.h文件,并且要先引用b.h,后引用a.h,否则汇报变量类型未声明错误。

三、双引号和尖括号的区别?
双引号的查找顺序:
1、当前的头文件目录
2、编译器指定的头文件路径
3、系统变量指定的头文件路径
尖括号没有1.

四、C++的虚拟内存
1、代码段,包括只读存储区和文本区。前者存储字符串常量,后者存储机器代码。
2、数据段:存储程序中已初始化全局变量静态变量
3、bss 段:存储未初始化的全局变量和静态变量(局部+全局),以及所有被初始化为0的全局变量和静态变量。
4、堆区:调用new/malloc函数时在堆区动态分配内存,同时需要调用delete/free来手动释放申请的内存。
5、映射区:存储动态链接库以及调用mmap函数进行的文件映射。
6、栈:使用栈空间存储函数的返回地址、参数、局部变量、返回值

五、内存泄露的分类
1、堆内存泄露。malloc,realloc new等从堆中分配的一块内存,程序结束后没有通过调用对应的 free或者delete 删掉。
2、系统资源泄露。程序使用系统分配的资源比如 Bitmap,handle ,SOCKET等没有使用相应的函数释放掉。
3、基类的析构函数没有被定义为虚函数。当基类指针指向子类对象时,如果基类的析构函数不是virtual,那么子类的析构函数将不会被调用,子类的资源没有正确是释放,因此造成内存泄露。

六、new和malloc的区别
1、new是运算符,可以重载,malloc是库函数。
2、malloc分配的内存不够的时候,可以用realloc扩容。new没用这样操作。
3、new如果分配失败了会抛出bad_malloc的异常,而malloc失败了会返回NULL。
4、new分配内存按照数据类型进行分配,malloc分配内存按照指定的大小分配。
5、new如果分配失败了会抛出bad_malloc的异常,而malloc失败了会返回NULL。
6、malloc的返回值需要进行类型转化为需要的类型,而new的结果是一个指向制定对象的指针。
7、new在分配内存的同时调用析构函数,但是malloc不会。

七、共享内存相关api
Linux允许不同进程访问同一个逻辑内存,提供了一组API,头文件在sys/shm.h中。
1、新建共享内存shmget
int shmget(key_t key,size_t size,int shmflg);
key:共享内存键值,可以理解为共享内存的唯一性标记。
size:共享内存大小
shmflag:创建进程和其他进程的读写权限标识。
返回值:相应的共享内存标识符,失败返回-1
2、连接共享内存到当前进程的地址空间shmat
void *shmat(int shm_id,const void *shm_addr,int shmflg);
shm_id:共享内存标识符
shm_addr:指定共享内存连接到当前进程的地址,通常为0,表示由系统来选择。
shmflg:标志位
返回值:指向共享内存第一个字节的指针,失败返回-1
3、当前进程分离共享内存shmdt
int shmdt(const void *shmaddr);
4、控制共享内存shmctl
和信号量的semctl函数类似,控制共享内存
int shmctl(int shm_id,int command,struct shmid_ds *buf);
shm_id:共享内存标识符
command: 有三个值
IPC_STAT:获取共享内存的状态,把共享内存的shmid_ds结构复制到buf中。
IPC_SET:设置共享内存的状态,把buf复制到共享内存的shmid_ds结构。
IPC_RMID:删除共享内存
buf:共享内存管理结构体。

你可能感兴趣的:(C++编译与底层相关知识点复习笔记)