目录
void
gcc 和 g++的区别
gcc与g++都是GNU(组织)的一个编译器。
- gcc与g++都可以编译c代码与c++代码。但是:后缀为.c的,gcc把它当做C程序,而g++当做是C++程序;后缀为.cpp的,两者都会认为是C++程序。
- 编译阶段,g++会调用gcc,对于c++代码,两者是等价的,但是因为gcc命令不能自动和C++程序使用的库联接,所以通常用g++来完成链接。
- 编译可以用gcc/g++,而链接可以用g++或者gcc -lstdc++。因为gcc命令不能自动和C++程序使用的库联接(当然可以选择手动链接,使用命令如下),所以通常使用g++来完成联接。但在编译阶段,g++会自动调用gcc,二者等价。
gcc编译的四个步骤
cc编译C源码有四个步骤:
预处理 .i ----> 编译 .s ----> 汇编 .o ----> 链接
栈溢出原因和解决方式
堆栈溢出的最常见原因是过度深度或无限递归,其中函数调用自身的次数太多,以至于存储与每个调用关联的变量和信息所需的空间超出了堆栈的范围。
- Infinite recursion -> 如果递归算法可能递归未知次数或大量次数,则自己管理递归(通过维护自己动态分配的堆栈)或将递归算法转换为等效迭代算法
- Very deep recursion -> 确保任何递归算法在已知最大深度后终止
- Very large stack variables -> 不要在堆栈上分配大变量
C++内存泄漏的几种情况
- 在类的构造函数和析构函数中没有匹配的调用new和delete函数
- 没有正确地清除嵌套的对象指针
- 在释放对象数组时在delete中没有使用方括号
- 指向对象的指针数组不等同于对象数组
- 缺少拷贝构造函数
- 缺少重载赋值运算符
- 关于nonmodifying运算符重载的常见迷思
- 没有将基类的析构函数定义为虚函数
- 出现野指针
C++字节对齐
字节对齐原因:
1)平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据,某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常
2)硬件原因:经过内存对齐之后,CPU的内存访问速度大大提升,帮助cpu寻址。
对齐位数跟处理器位数和编译器都有关
改变缺省的对界条件(指定对界):
使用伪指令#pragma pack (n),C编译器将按照n个字节对齐。
使用伪指令#pragma pack (),取消自定义字节对齐方式。
#pragma pack (8)
struct MyStruct
{
double dda1; //8
char dda; //1
int type; //4
short t2; //2
};
int main()
{
printf("%d
", sizeof(MyStruct)); //24
return 0;
}
输出为24:
- double是8字节,现在偏移量是8
- char是1字节,偏移量8是1的整数倍满足条件,现在偏移量为8+1=9
- int是4字节,偏移量9不是4的整数倍故先填充3个字节才能满足条件,现在偏移量为9+3+4=16
- short是2字节,偏移量16是2的整数倍满足条件,后面没了,故补齐至8,现在偏移量为16+8=24
#pragma pack (8)
是64位编译器的默认对齐方式,如果改为#pragma pack (4)
则输出为20。
[1]. Stack overflow. https://en.wikipedia.org/wiki/Stack_overflow