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;
    }
  • 相关阅读:
    multiprocessing.Pool报pickling error
    Python 数据库的Connection、Cursor两大对象
    python中的tcp示例详解
    Python网络编程篇之select和epoll
    python select epoll poll的解析
    python网络编程——IO多路复用之epoll
    python实现并发服务器实现方式(多线程/多进程/select/epoll)
    python select模块
    CRM客户关系管理系统(七)
    CRM客户关系管理系统(六)
  • 原文地址:https://www.cnblogs.com/1203ljh/p/4733766.html
Copyright © 2011-2022 走看看