野指针问题

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\n", (p==NULL) ? 1 : 0);                // 0     ----> p指针释放后未置空
    printf("%d\n", *p);                               // ?     ----> 未阻止对到账内存访问
    *p = 20;                                          //       ----> 未阻止对到账内存访问
    printf("%d\n", *p);                               // 20    ----> 未阻止对到账内存访问

    /*-------------------------------- 以 下 正 确 写 法 --------------------------------*/
    delete p;
    p = NULL;
    printf("%d\n", (p==NULL) ? 1 : 0);                // 1     ----> p指针释放后已置空
    if(p!=NULL)                                       //       ----> 不加判断三条语句都崩溃
    {
        printf("%d\n", *p);                           //       ----> 阻止了对到账内存的访问
        *p = 20;                                      //       ----> 阻止了对到账内存的访问
        printf("%d\n", *p);                           //       ----> 阻止了对到账内存的访问
    }
    return 0;
}
时间: 2024-11-06 21:43:45

野指针问题的相关文章

21 野指针

分析下列程序,输出结果:不确定,未定义行为. #include<iostream> #include<stdlib.h> #include<string.h> using namespace std; void test(void) { char *str=(char *)malloc(100); strcpy(str,"hello"); free(str); if(str!=NULL) { strcpy(str,"world")

C语言指针2(空指针,野指针)

//最近,有朋友开玩笑问 int *p  *是指针还是p是指针还是*p是指针,当然了,知道的都知道p是指针 //野指针----->>>指没有指向一个地址的指针(指针指向地址请参考上一篇文章) //空指针---->>指向空(null)的指针就是空指针 //指针的其他用法,指针可以指向指针,指针可以进行+ - * /运算 /* 特别注意,各个编译器都不相同,这里有一种错误写法,如: int *p,int a=10,b=20; p=&b; *p = &a;    

野指针

参考:http://chenqx.github.io/2014/09/25/Cpp-Memory-Management/ 内存管理详解 野指针: 一.申请了指针没有初始化,全局指针未初始化编译时无错误,运行会出错,局部指针编译时会报错--unintialized: 二.malloc申请的内存用free(ptr)释放后,ptr指向的是垃圾内存,或者new出来的对象delete之后,指针所指的对象释放掉了,指针还存在,但指向的是垃圾内存,对待这种错误,可以在释放掉后把指针置为NULL: 三.函数返回

野指针的学习

1.野指针     野指针是指向了"垃圾"内存的指着. 2.产生原因     (1)指针变量没有被初始化.任何指针变量刚刚被创建的时候,是不会自动变成NULL指针的,他的缺省值是随机的,这个时候指针是乱指的.所以指针变量在被创建的同时应该被初始化,让指针指向合法的内存.     (2)指针P被free或者delect之后,没有设置为NULL:当指着被free之后,其实就是释放了指针指向这块内存进行释放,也就是说指针依旧是指向这个地址,但是这个地址上面的东西不要了,并且系统也不会将这块内

野指针 空指针 通用指针

空指针是一个特殊的指针值,也是唯一一个对任何指针类型都合法的指针值.指针变量具有空指针值,表示它当时处于闲置状态,没有指向有意义的东西.空指针用0表示,C语言保证这个值不会是任何对象的地址.给指针值赋零则使它不再指向任何有意义的东西.为了提高程序的可读性,标准库定义了一个与0等价的符号常量NULL.    程序里可以写 p = 0;     或者 p = NULL; 两种写法都把p置为空指针值.相对而言,前一种写法更容易使读程序的人意识到这里是一个指针赋值.操作NULL也会导致不可预知的错误 我

关于空指针NULL、野指针、通用指针

http://www.cnblogs.com/losesea/archive/2012/11/16/2772590.html 首先说一下什么是指针,只要明白了指针的含义,你就明白null的含义了.假设 有语句 int a=10;那么编译器就在内存中开辟1个整型单元存放变量a,我们假设这个整型单元在内存中的地址是 0x1000:那么内存0x1000单元中存放了数据10,每次我们访问a的时候,实际上都是访问的0x1000单元中的10.现在定义:int *p:                 p=&a

c++中的悬浮指针和野指针 二级指针

(1) c++中的悬浮指针:声明了但没有被付值的指针,它指向内存中的任意一个空间.避免悬浮指针的一个方法是开始就付值为NULL (2)"野指针"不是NULL指针,是指向"垃圾"内存的指针.人们一般不会错用NULL指针,因为用if语句很容易判断.但是"野指针"是很危险的,if语句对它不起作用.野指针的成因主要有两种: 一.指针变量没有被初始化.任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的,它会乱指一气.所以,指针变量在创建的同

野指针错误实例

野指针,也就是指向不可用内存区域的指针.通常对这种指针进行操作的话,将会使程序发生不可预知的错误. 这是野指针的定义,但很多C语言新手对它还是很陌生,下面我就简单举一个例子来看一看.在VC6.0中输入以下代码: #include <malloc.h> #include <stdio.h> void main() { char *p; //...可能有别的很多操作 if(p != NULL) { free(p); } else { p = (char *)malloc(4); } /

View野指针问题分析报告

[问题描述] 音乐组同事反馈了一个必现Native Crash问题,tombstone如下: pid: 5028, tid: 5028, name: com.miui.player >>> com.miui.player <<< signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 79801f28 r0 7ac59c98 r1 00000000 r2 bea7b174 r3 400fc1b8 r4 774c4c88

Virsualizer模块野指针问题分析报告

[NE现场] pid: 1040, tid: 19988, name: Visualizer >>> com.android.systemui <<< signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 546f2cf8 r0 56106e28 r1 546f2d18 r2 0200000f r3 02000008 r4 56106e28 r5 546f2d18 r6 566f2d24 r7 566f2d20 r8