悬挂指针
指针所指的对象已经消亡
指针指向某个对象之后,当这个对象的生命周期已经结束,对象已经消亡后,仍使用指针访问该对象,将出现运行时错误。考察如下程序。
#include <iostream>
using namespace std;
int* retAddr(){
int num=10;
return #
int main(){
int* p=NULL;
p=retAddr();
cout<<&p<<endl;
cout<<*p<<endl;
以上程序编译和运行都没有错误,输出结果如下:
最后一行,输出的并非想象中的num的值10,因为变量num是存储在栈空间的局部变量,离开函数超出其作用域后就会被释放掉,因此输出的值就是不确定的值了。
如果将cout<<&p<
VC++和g++都是这样,
VS会在return #处发出警告
//warning C4172: 返回局部变量或临时变量的地址: num
但并不会在运行时报错。
悬挂指针
指针释放后之后未置空
指针p被free或者delete之后,没有置为NULL,让人误以为p是个合法的指针。对指针进行free和delete,只是把指针所指的内存空间给释放掉,但并没有把指针本身置空,此时指针指向的就是“垃圾”内存。释放后的指针应立即将指针置为NULL,防止产生悬挂指针。考察如下程序。
#include <iostream>
using namespace std;
int main(){
int* p=NULL;
p=new int[10];
delete p;
cout<<"p[0]:"<<p[0]<<endl;
程序输出结果是一个随机值,因为此时的指针所指向的空间是垃圾内存,存放着随机值。
悬挂指针
另在C语言中、realloc函数
1
2
3
4
5
6
7
8
9
|
#include
void main()
{
char*p,*q;
p=(char*)malloc(10);
q=p;
p=(char*)realloc(q,20);
//…………………………
}
|
|
|
在这段程序中我们用q记录原来的
内存地址
p。这段程序可以编译通过,但在执行到7行时,若原内存后面没有足够空间来将原有空间扩展成一个连续的新大小,那么
realloc函数
会从堆中重新找一块30字节大小的内存,并把原来(通过调用malloc函数得到的)内存空间中的内容复制到这块新内存中,此时数据发生了移动,那么q所指向(通过调用malloc函数得到的)的内存空间实际上已经放回到堆上了!这样就会产生q指针的指针悬挂,此时如果再用q指针进行操作就可能发生意想不到的问题。