1、C++指针
指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。就像其他变量或常量一样,必须在使用指针存储其他变量地址之前,对其进行声明。
& 是一元运算符,返回操作数的内存地址。例如,如果 var
是一个整型变量,则 &var
是它的地址。该运算符与其他一元运算符具有相同的优先级,在运算时它是从右向左顺序进行的。
*
是一元运算符,返回操作数所指定地址的变量的值。指针声明示例如下:
int *ip; /* 一个整型的指针 */double *dp; /* 一个 double 型的指针 */float *fp; /* 一个浮点型的指针 */char *ch; /* 一个字符型的指针 */
2、指针的使用
变量定义的时候给变量初始化,没有给指针初始化,就会出现野指针,该指针的指向并不是我们所希望的,一旦错误的释放了这个指针,就会发生内存的访问。指针使用之后,如果不释放指针所使用的内存,就会造成内存的泄露,这样就会有大量内存由于没能释放,别的程序不可以使用这部分内存,如果一个程序不停申请内存而不去释放内存,很快就会造成系统的崩溃。在使用指针时一定要判断指针是否为空,如果为空,则做相应的操作。如果不做判断,则可能错误的使用空指针。
例如,
#includeusing namespace std; int main (){ int var = 20; /* 实际变量的声明 */ int *ip; /* 指针变量的声明 */ ip = &var; /* 在指针变量中存储 var 的地址 */ cout << "var 变量的地址: " << &var << endl; /* 在指针变量中存储的地址 */ cout << "ip 变量存储的地址: " << ip << endl; /* 使用指针访问值 */ cout << "*ip 变量的值: " << *ip << endl; /*使用空指针初始化*/ int *pIntegerVal=NULL; /*用变量初始化指针*/ int length=5; int *pIntegerTemp=&length; /*分配内存初始化指针*/ int *pInteger=(int*)malloc(10*sizeof(int)); //为指针分配大小为10个整数的内存空间。 /*内存申请和释放*/ if(pInteger != NULL) { free(pInteger); pInteger=NULL;//指针释放之后并不为空,要设置其为空 } pInteger=(int*)malloc(10*sizeof(int)); if(pInteger == NULL) { cout << "内存申请没有成功\n!"; } return 0;}
3、C++ 中的 NULL 指针
变量声明的时候,如果没有确切的地址可以赋值,为指针变量赋一个 NULL
值。赋为 NULL
值的指针被称为空指针。
NULL
指针是一个定义在标准库中的值为零的常量。这样能很好的避句野指针。
例如,
#includeusing namespace std;int main (){ int *ptr = NULL; cout << "ptr 的地址是 " << ptr << endl; return 0;}
注意:
大多数的操作系统上,程序不允许访问地址为 0
的内存,因为该内存是操作系统保留的。然而,内存地址 0
有特别重要的意义,它表明该指针不指向一个可访问的内存位置。
4、nullptr 关键字
nullptr
关键字就是表示空指针,C++11之前空指针都是NULL
。nullptr
表示空指针,不能转换为整型类型。为了向后兼容,C++11仍允许用0(NULL)
来表示空指针。nullptr
相比0(NULL)
具有更高的类型安全,推荐使用nullptr
。
5、C++ 智能指针
C++里面的四个智能指针: auto_ptr
, shared_ptr
, weak_ptr
, unique_ptr
其中后三个是c++11支持,并且第一个已经被11弃用。智能指针的作用是管理一个指针。因为可能申请的空间在函数结束时忘记释放,造成内存泄漏。使用智能指针可以很大程度上的避免这个问题,智能指针就是一个类,当超出了类的作用域,类会自动调用析构函数,析构函数会自动释放资源。所以智能指针的作用原理就是在函数结束时自动释放内存空间,不需要手动释放内存空间。
1)auto_ptr
c++98的方案,c++ 11已经抛弃。
2)shared_ptr
shared_ptr
采用引用计数的方式管理所指向的对象。当有一个新的shared_ptr
指向同一个对象时(复制shared_ptr
等),引用计数加1。当shared_ptr
离开作用域时,引用计数减1。当引用计数为0
时,释放所管理的内存。
3)weak_ptr
weak_ptr
一般和shared_ptr
配合使用。它可以指向shared_ptr
所指向的对象,但是却不增加对象的引用计数。当出现weak_ptr
所指向的对象实际上已经被释放了的情况。weak_ptr
有一个lock
函数,尝试取回一个指向对象的shared_ptr
。
4)unique_ptr
unique_ptr
对于所指向的对象, 指向的对象是独占的。不可以对unique_ptr
进行拷贝、赋值等操作,但是可以通过release
函数在unique_ptr
之间转移控制权。