moc 发表于 2018-8-19 10:06:16

015-野指针

1、野指针及成因
        野指针指向一个已删除的对象或未申请访问受限内存区域的指针。与空指针不同,野指针无法通过简单地判断是否为 NULL避免,而只能通过养成良好的编程习惯来尽力减少。
成因:
        1.指针变量未初始化
                任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的,它会乱指一气。所以,指针变量在创建的同时应当被初始化,要么将指针设置为NULL,要么让它指向合法的内存。如果没有初始化,编译器会报错“ ‘point’ may be uninitializedin the function ”。
        2.指针释放后之后未置空
                有时指针在free或delete后未赋值 NULL,便会使人以为是合法的。别看free和delete的名字(尤其是delete),它们只是把指针所指的内存给释放掉,但并没有把指针本身干掉。此时指针指向的就是“垃圾”内存。释放后的指针应立即将指针置为NULL,防止产生“野指针”。
        3.指针操作超越变量作用域
                不要返回指向栈内存的指针或引用,因为栈内存在函数结束时会被释放。
2、野指针的规避
三步走:
        1.初始化的是定义指针变量的时候,指针变量赋值成null
        2. 释放的时候,判断是不是null,如果是NULL则不释放
        3. 释放完毕以后再赋值成null
3、程序示例
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "malloc.h"

// 创建二维内存空间给指针
char ** spitString_Creat(int mycount)
{
        int i = 0;
        char **myarray = NULL;

        if (mycount > 1000)      // 如果要求创建空间大于1000,不予创建
        {
                return NULL;
        }

        myarray = (char **)malloc(mycount * sizeof(char *));
        if (myarray == NULL)
        {
                return NULL;
        }
        for (i = 0; i<10; i++)
        {
                myarray = (char *)malloc(100);
        }

        return myarray;
}

// 释放创建的二维内存空间
voidspitString05_free(char **myarray, int ncount)
{
        int i = 0;
        if (myarray == NULL)
        {
                return;
        }
        for (i = 0; i<ncount; i++)
        {
                if (myarray != NULL) free(myarray);
        }
        if (myarray != NULL)
        {
                free(myarray);
        }
        // 下面在函数中直接修改形参的值,是不会改变实参的值
        // 函数调用中,用3级指针(形参)才能去修改2级指针(实参)的值,所以下面的修改并不会反映到实参中。
        myarray = NULL; //垃圾
}

void main()
{
        inti = 0;
        int ncount = 10;
        char **myarray = NULL;

        //1初始化的是定义指针变量的时候,指针变量赋值成null
        char ** myarray1 = NULL;
        char **myarray2 = NULL;
        char **myarray3 = NULL;

        myarray1 = spitString_Creat(10);
        if (myarray1 == NULL)
        {
                printf("func spitString_Creat() \n");
                goto End;         // 合理使用goto,无条件转移
        }

        myarray2 = spitString_Creat(10000);
        if (myarray2 == NULL)
        {
                printf("func spitString_Creat() \n");
                goto End;
        }

        myarray3 = spitString_Creat(10);
        if (myarray3 == NULL)
        {
                printf("func spitString_Creat() \n");
                goto End;
        }

        for (i = 0; i<ncount; i++)
        {
                printf("%s\n", myarray);
        }

End:
        //2 释放的时候,判断是不是null
        //3 释放完毕以后再赋值成null
        if (myarray1 != NULL)
        {
                spitString05_free(myarray1, 10);
                myarray1 = NULL;
        }

        if (myarray2 != NULL)
        {
                spitString05_free(myarray2, 10);
                myarray2 = NULL;
        }

        if (myarray3 != NULL)
        {
                spitString05_free(myarray3, 10);
                myarray3 = NULL;
        }

        system("pause");
}
页: [1]
查看完整版本: 015-野指针