野指针

野指针指向一个已删除的对象或未申请访问受限内存区域的指针。
与空指针不同,野指针无法通过简单地判断是否为 NULL避免,而只能通过养成良好的编程习惯来尽力减少。对野指针进行操作很容易造成程序错误。

1. 指针变量未初始化

任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的,它会乱指一气。
所以,指针变量在创建的同时应当被初始化,要么将指针设置为NULL,要么让它指向合法的内存。
2. 指针释放后之后未置空
有时指针在free或delete后未赋值 NULL,便会使人以为是合法的。别看free和delete的名字
(尤其是delete),它们只是把指针所指的内存给释放掉,但并没有把指针本身干掉。
此时指针指向的就是“垃圾”内存。释放后的指针应立即将指针置为NULL,防止产生“野指针”。
3. 指针操作超越变量作用域
不要返回指向栈内存的指针或引用,因为栈内存在函数结束时会被释放。

class A {
public:
    void Func(void){ cout << “Func of class A” << endl; }
};

class B {
public:
    A *p;
    void Test(void) {
        A a;
        p = &a; // 注意a的生命期 ,只在这个函数Test中,而不是整个class B
    }

    void Test1() {
        p->Func(); // p 是“野指针”
    }
};

函数Test1在执行语句p->Func()时,p的值还是a的地址,对象a的内容已经被清除,所以p就成了“野指针”。

 

指针变量一定要初始化为NULL,因为任何指针变量(除了static修饰的指针变量)刚被创建时不会自动成为NULL指针,它的缺省值是随机的。
万一指针没有被初始化而拿来用则会引起意想不到的结果,而且表面上还看不出程序出错。

int *p = NULL;  //p指针申明时最好赋值为NULL,否则他是随机的,取决于内存分配时这块内存本身的值。

 

void test( void ) {   
    char *str = (char *) malloc( 100 );
    if (str == null) {  // 必须判断内存是否申请成功,防止OOM
        exit(1);
    }

    strcpy( str, "hello" );
    free( str );
    str = NULL     //释放后str必须赋值为NULL 防止成为野指针。
}

 

swap( int* p1,int* p2 ) 
{
    int *p;
    *p = *p1;
    *p1 = *p2;
    *p2 = *p;
} 
//p指针未初始化,是个野指针
swap( int* p1,int* p2 ) 
{
    int p;
    p = *p1;
    *p1 = *p2;
    *p2 = p;
}

 

void getMemory(char *p)
{
    p = (char*) malloc(100);
if (p == NULL) {
exit(1);
} }
void test() { char *str = NULL; getMemory(str); strcpy(str, "hello"); free(str);
str = NULL; }

p作为局部变量在test()函数中根本没有被改变。  参数*p 改变的是p指向的内存空间。

 

posted @ 2016-12-08 10:13  牧 天  阅读(234)  评论(0)    收藏  举报