再探C++Primer (4)指针、引用、对象和内存

原创
2016/07/07 18:38
阅读数 77

###基本内置类型和复合类型#

基本内置类型就是算数类型和空类型,算数类型包括字符、整数、布尔值、浮点数,空类型是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个内存分配区域:

  1. 。栈就是编译器需要时分配,不需要时自动清理的变量的存储区,这些变量通常是局部变量函数参数临时变量等;
  2. 。堆就是由我们new 出的对象的存储区,编译器不管他们的释放,所以通常一个new 对应一个delete,如果程序员没有释放掉,那么程序结束后操作系统自动回收。
  3. 自由存储区。通过malloc 等分配的内存,他们和堆类似,但是使用free 来结束声明并释放;
  4. 全局/静态存储区全局变量静态变量 的存储区;
  5. 常量存储区。顾名思义,存放常量 且不允许修改。

关于堆和栈的内容,属于数据结构方面的,栈是一种先进先出的线性表,堆是一种树形结构。

####内存泄漏和野指针#

内存泄漏

主要是指堆和自由存储区内存泄漏,通常由于new或者是malloc之后没有delete或free掉,导致申请的对象空间在使用完毕后依然停留在内存中,特别是在局部new出的变量,由于局部指针在脱离其作用域后已经失效,而申请的空间没有释放导致再也无法释放,就是内存泄漏。

内存泄漏会占用内存空间,降低程序运行效率,特别是当内存泄漏的操作存在于高频率执行的环境下,例如循环体或者递归中,那么系统内存消耗将不断增加,直到最终因没有可分配内存而崩溃。

野指针

是指两种情况:

  1. 指针没有初始化;
  2. 指针被free或delete后,没有被置为0或NULL或nullptr.

野指针被使用后,由于编译器不会检查此类错误,所以往往容易造成我们难以发现和理解的错误,所以

  1. 应该对指针进行初始化;
  2. 在free或delete指针后,将其置为nullptr或NULL或0;
  3. 不要返回指向栈内存的指针或引用,因为栈内存在函数结束时会被释放.
展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部