zoukankan      html  css  js  c++  java
  • 野指针问题

    1. 定义:

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

    2. 形成原因:

    (1)指针变量未初始化

      任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的,它会乱指一气。所以指针变量在创建的同时应当被初始化,要么将指针设置为NULL,要么让它指向合法的内存。

    (2)指针释放之后未置空

      有时指针在free或delete后未赋值 NULL,便会使人以为是合法的。别看free和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 就成了“野指针” 。

    3. 测试代码:

    #include <stdio.h>
    #include <iostream>
    using namespace std;
    
    int main()
    {
        int *ppp = NULL;                                  //       ----> 合法方法3
    
        int num = 10;
        int *pp;
        pp = &num;                                        //       ----> 合法方法2
    
        int *p = new int;                                 //       ----> 合法方法1
        *p = 10;
    
        /*-------------------------------- 以 下 错 误 写 法 --------------------------------*/
        delete p;
        printf("%d
    ", (p==NULL) ? 1 : 0);                // 0     ----> p指针释放后未置空
        printf("%d
    ", *p);                               // ?     ----> 未阻止对到账内存访问
        *p = 20;                                          //       ----> 未阻止对到账内存访问
        printf("%d
    ", *p);                               // 20    ----> 未阻止对到账内存访问
    
        /*-------------------------------- 以 下 正 确 写 法 --------------------------------*/
        delete p;
        p = NULL;
        printf("%d
    ", (p==NULL) ? 1 : 0);                // 1     ----> p指针释放后已置空
        if(p!=NULL)                                       //       ----> 不加判断三条语句都崩溃
        {
            printf("%d
    ", *p);                           //       ----> 阻止了对到账内存的访问
            *p = 20;                                      //       ----> 阻止了对到账内存的访问
            printf("%d
    ", *p);                           //       ----> 阻止了对到账内存的访问
        }
        return 0;
    }
  • 相关阅读:
    作业3——turtle
    作业2——Python基础
    作业——理解管理信息系统
    测试用例挑选策略
    UVALive 5903 Piece it together(二分图匹配)
    UVALive 4953 Wormly--【提醒自己看题要仔细】
    HDU 3111 Sudoku(精确覆盖)
    FZU 2165 v11(最小重复覆盖)+ codeforces 417D Cunning Gena
    UVALive 6577 Binary Tree 二叉树的LRU串
    codeforces 425C Sereja and Two Sequences(DP)
  • 原文地址:https://www.cnblogs.com/1203ljh/p/4733766.html
Copyright © 2011-2022 走看看