###基本内置类型和复合类型#
基本内置类型就是算数类型和空类型,算数类型包括字符、整数、布尔值、浮点数,空类型是void;
复合类型指基于其他类型定义的类型,例如指针和引用。
###引用#
- 引用就是给对象起的别名,通过声明对象时在对象标识符前加‘&’符号来定义引用类型。例如:int a=100;int &b=a;则可以通过对b的操作来操作变量a;
- 引用本身并不是对象,只是对象的别名,在内存中没有具体的存在;
- 引用只与其初始化的对象绑定在一起,初始化后不能将引用绑定到其他对象上;
- 引用只能绑定在对象上而不能绑定在表达式或字面值常量上。
###指针#
- 指针同引用近似,提供了对其他对象的间接访问;
- 指针是一个独立的对象,允许对指针进行赋值和拷贝,定义指针后,根据计算机位数不同在内存中占据不同的大小,例如32位计算机/32位编译器中,指针大小是4字节;
- 指针存储的是对象在内存中的逻辑地址;
- 指针可以不被初始化也可以在生命周期内指向多个对象。
####获取对象地址、利用指针访问对象#
指针一般要求指针类型同其所指对象严格匹配
int a = 10;
int *b;
b = &a; //通过取地址符获取变量a地址
int c = *b; //通过解引用符获取指针b所指变量
double *d = a; //错误,指针类型同所指对象不匹配
指针可以不被初始化,通过取地址符&可以获取对象地址,通过解引用符*可以获取指针所指对象。
####指针值及一些好习惯#
指针值有四种类型:
- 指向一个对象
- 指向紧邻对象所占空间的下一个位置
- 空指针,没有指向任何对象
- 无效指针,没有指向有效对象
注意:无效指针不等于空指针,无效指针指向了一个未知的位置,而空指针为0值,所以
int *a;
if (a)
std::cout<<'1'<<endl;
else
std::cout<<'0'<<endl;
将输出为1。
试图以任何方式访问无效指针都引发错误,编译器不负责检查此类错误,无效指针导致了大多数令我们痛苦的bug和问题,所以应该养成初始化指针的好习惯。
如果无法确定指针的初值,那么应该让他们等于0或者NULL或者nullptr。
###对象和内存#
在C++中有以下5个内存分配区域:
- 栈。栈就是编译器需要时分配,不需要时自动清理的变量的存储区,这些变量通常是局部变量、函数参数、临时变量等;
- 堆。堆就是由我们new 出的对象的存储区,编译器不管他们的释放,所以通常一个new 对应一个delete,如果程序员没有释放掉,那么程序结束后操作系统自动回收。
- 自由存储区。通过malloc 等分配的内存,他们和堆类似,但是使用free 来结束声明并释放;
- 全局/静态存储区,全局变量 和静态变量 的存储区;
- 常量存储区。顾名思义,存放常量 且不允许修改。
关于堆和栈的内容,属于数据结构方面的,栈是一种先进先出的线性表,堆是一种树形结构。
####内存泄漏和野指针#
内存泄漏
主要是指堆和自由存储区内存泄漏,通常由于new或者是malloc之后没有delete或free掉,导致申请的对象空间在使用完毕后依然停留在内存中,特别是在局部new出的变量,由于局部指针在脱离其作用域后已经失效,而申请的空间没有释放导致再也无法释放,就是内存泄漏。
内存泄漏会占用内存空间,降低程序运行效率,特别是当内存泄漏的操作存在于高频率执行的环境下,例如循环体或者递归中,那么系统内存消耗将不断增加,直到最终因没有可分配内存而崩溃。
野指针
是指两种情况:
- 指针没有初始化;
- 指针被free或delete后,没有被置为0或NULL或nullptr.
野指针被使用后,由于编译器不会检查此类错误,所以往往容易造成我们难以发现和理解的错误,所以
- 应该对指针进行初始化;
- 在free或delete指针后,将其置为nullptr或NULL或0;
- 不要返回指向栈内存的指针或引用,因为栈内存在函数结束时会被释放.
来源:oschina
链接:https://my.oschina.net/u/2760487/blog/707932