迷途指针

来源:互联网 发布:张恩民 php视频教程 编辑:程序博客网 时间:2024/06/02 12:27

有关指针的争论备受瞩目。这是因为在程序中由于指针引发的错误可能是最难发现和最难解决的。在C++中导致难以发现和解决的错误的罪魁祸首是迷途(stray)指针。迷途指针也被称为失控(wild)指针或悬浮(dangling)指针,是将delete用于指针(从而释放它指向的内存),但没有将它设置为空时引发的。如果随后你在没有重新赋值的情况下使用该指针,后果将是不可预料的:程序崩溃算你走运。

就如同交通银行变更了号码,但你仍去按原来绑定的按钮。这可能不会导致什么严重后果——也许这将拨向一个无人仓库的电话,另一方面,也许这个号码已经被重新分配给了一个军工厂,你拨打电话可能引发爆炸,将整个城市摧毁。

总之,对指针delete后就不要再使用它。虽然这个指针仍然指向原来的内存区域,但编译器可能已经将其它数据存储在这里。不重新给这个指针赋值就再次使用它可能导致程序崩溃;更糟糕的是,程序可能表面上运行正常,但过不了几分钟就崩溃了。这被称为定时炸弹。为了安全起见,删除指针后,把其设置空(0),这样便解除了它的武装。

示例:

我的运行结果:

*pInt: 10       pInt address: 0x3d2488
*pLong: 90000   pLong address: 0x3d2488
*pInt: 20       0x3d2488
*pLong: 65556   0x3d2488

请按任意键继续. . .


分析

在程序清单中,pLong指向的内存的值变为65556的过程如下:

  1. 指针pInt指向某个内存块,并将10存储到该内存块中。
  2. 将delete用于指针pInt,这相当于告诉编译器,可以将内存块用于存储其它东西。然后指针pLong指向该内存块。
  3. 将90000赋给*pLong。在这个例子中使用的计算机按字节交换顺序存储4字节值90000(00 01 5f 90),因此被存储为 5f 90 00 01。
  4. 将20(十六进制表示为00 14)赋给*pInt。由于pInt仍然指向原来的地址,因此pLong的前两个字节被覆盖,变成了00 14 00 01。
  5. 打印*pLong的值,将字节反转为正确的顺序00 01 00 14,然后被转换为DOS值65556。

讨论:迷途指针和空指针

声明定义一个指针myPtr,然后将delete用于该指针,实际上是让编译器释放内存,但指针本身依然存在。它现在是个迷途指针。

如果接下来使用myPtr = 0;  该迷途指针将变为空指针。

通常如果对指针使用delete后再次对其使用delete,后果是不确定的,也就是说,任何事情都有可能发生。但对空指针使用delete,什么也不会发生,这样做是安全的。

使用迷途指针或空指针都是非法的(illegal),例如写myPtr=5;  可能导致程序崩溃(crash)。使用空指针,程序也将崩溃,但相对于迷途指针来说,可预测的崩溃更可取,因为这更容易调试。