C++中的一个重要概念及其特点,也是掌握C++比较困难的部分。指针也就是内存地址,指针变量是用来存放内存地址的变量,不同类型的指针变量所占用的存储单元长度是相同的,而存放数据的变量因数据的类型不同,所占用的存储空间长度也不同。有了指针以后,不仅可以对数据本身,也可以对存储数据的变量地址进行操作。本文主要介绍C++中的指针。

1、C++指针

指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。就像其他变量或常量一样,必须在使用指针存储其他变量地址之前,对其进行声明。

& 是一元运算符,返回操作数的内存地址。例如,如果 var 是一个整型变量,则 &var 是它的地址。该运算符与其他一元运算符具有相同的优先级,在运算时它是从右向左顺序进行的。

*是一元运算符,返回操作数所指定地址的变量的值。指针声明示例如下:

int    *ip;    /* 一个整型的指针 */
double *dp;    /* 一个 double 型的指针 */
float  *fp;    /* 一个浮点型的指针 */
char   *ch;    /* 一个字符型的指针 */

2、指针的使用

变量定义的时候给变量初始化,没有给指针初始化,就会出现野指针,该指针的指向并不是我们所希望的,一旦错误的释放了这个指针,就会发生内存的访问。指针使用之后,如果不释放指针所使用的内存,就会造成内存的泄露,这样就会有大量内存由于没能释放,别的程序不可以使用这部分内存,如果一个程序不停申请内存而不去释放内存,很快就会造成系统的崩溃。在使用指针时一定要判断指针是否为空,如果为空,则做相应的操作。如果不做判断,则可能错误的使用空指针。

例如,

#include <iostream>
using 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 指针是一个定义在标准库中的值为零的常量。这样能很好的避句野指针。

例如,

#include <iostream>
using namespace std;
int main ()
{
   int  *ptr = NULL;
   cout << "ptr 的地址是 " << ptr << endl;
   return 0;
}

注意:

大多数的操作系统上,程序不允许访问地址为 0 的内存,因为该内存是操作系统保留的。然而,内存地址 0 有特别重要的意义,它表明该指针不指向一个可访问的内存位置。

4、nullptr 关键字

nullptr关键字就是表示空指针,C++11之前空指针都是NULLnullptr表示空指针,不能转换为整型类型。为了向后兼容,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之间转移控制权。

推荐文档