当前位置 博文首页 > 文章内容

    C++野指针和悬空指针的实现方法

    作者:shunshunshun18 栏目:未分类 时间:2021-08-08 14:44:42

    本站于2023年9月4日。收到“大连君*****咨询有限公司”通知
    说我们IIS7站长博客,有一篇博文用了他们的图片。
    要求我们给他们一张图片6000元。要不然法院告我们

    为避免不必要的麻烦,IIS7站长博客,全站内容图片下架、并积极应诉
    博文内容全部不再显示,请需要相关资讯的站长朋友到必应搜索。谢谢!

    另祝:版权碰瓷诈骗团伙,早日弃暗投明。

    相关新闻:借版权之名、行诈骗之实,周某因犯诈骗罪被判处有期徒刑十一年六个月

    叹!百花齐放的时代,渐行渐远!



    野指针和悬空指针是指针中常见的两个概念,本文结合实例讲解来讲解下。

    一、野指针

    野指针是指尚未初始化的指针,既不指向合法的内存空间,也没有使用 NULL/nullptr 初始化指针。

    来看一个简单例子:

    #include <iostream>
    using namespace std;
     
    int main()
    {
        int *p;     // 野指针
        int *q = NULL; // 非野指针
        p = new int(5);  // p 现在不再是野指针
        q = new int(10); 
        cout<<"*p = "<<*p<<endl;
        cout<<"*q = "<<*q<<endl;
        free(p);
        free(q);
        return 0;
    }
    

    输出结果为:

    linuxy@linuxy:~/wildPointer$ ./main
    *p = 5
    *q = 10
    linuxy@linuxy:~/wildPointer$

    p 在定义时并没有赋初值,这时候为野指针。

    二、悬空指针

    悬空指针是指 指针指向的内存空间已被释放或不再有效。

    有三种情况会产生悬空指针,下面结合实例来看一下:

    2.1 情况一

    释放指针资源后,未再次赋值前。

    #include <iostream>
    using namespace std;
     
    int main()
    {
        int *p = new int(5);
        cout<<"*p = "<<*p<<endl;
        free(p);  // p 在释放后成为悬空指针
        p = NULL; // 非悬空指针
        return 0;
    }
    

    p 指针在被 free 后,成为悬空指针,被 NULL 赋值后不再是悬空指针。

    注意:这里 free 掉的是 p 的内存空间,并不是变量 p,结合一个例子看下:

    #include <iostream>
    using namespace std;
     
    int main()
    {
        int *p = new int(5);
        cout<<"*p = "<<*p<<endl;
        cout<<"p 地址:"<<p<<endl;
        free(p);  // p 在释放后成为悬空指针
        cout<<"p 地址:"<<p<<endl;
        cout<<"*p = "<<*p<<endl;
        p = NULL; // 非悬空指针
        return 0;
    }
    

    输出结果为:

    linuxy@linuxy:~/wildPointer$ ./main
    *p = 5
    p 地址:0x55a885ef6eb0
    p 地址:0x55a885ef6eb0
    *p = 0
    linuxy@linuxy:~/wildPointer$

    可以看到, free 前后 p 的地址是不变的,free 释放的是 p 指向的内存空间,释放后表示该快内存可以重新分配了,至于 free 后 *p 的值,视不同编译器情况而不同。

    2.2 情况二

    超出了变量的作用范围。

    #include <iostream>
    using namespace std;
     
    int main()
    {
        int *p;
        {
            int tmp = 10;
            p = &tmp;
        }
        //p 在此处成为悬空指针
        return 0;
    } 
    

    在上述例了中,变量 tmp 的作用范围为最近的一层括号内,在括号外引用便超出了变量的作用范围。

    2.3 情况三

    指向了函数局部变量。

    #include <iostream>
    using namespace std;
     
    int* getVal() {
        int tmp = 10;
        return &tmp;
    }
     
    int main()
    {
        int *p = getVal(); //悬空指针
        cout<<"*p = "<<*p<<endl;
        return 0;
    }
    

    在函数 getVal 执行完后,局部变量的内存空间会被释放,而这里 p 指向了函数内的局部变量,p 便成为了悬空指针,可以将 tmp 变为 static 的。