空指针 野指针 void*

本文详细解析了空指针与野指针的概念及其区别,并通过实例演示了如何避免野指针的出现,同时介绍了void*的特性和使用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、空指针的理解
1、指针定义后要声明,不然就是野指针。
2、指针的值是0,意味着该指针是空指针。
    为什么是这样,因为NULL在C++中是个宏定义:
//Define NULL pointer value
#ifndef NULL
#    ifdef    __cplusplus
#        define    NULL    0
#    else
#        define    NULL    ((void *)0)
#    endif
#endif    //NULL
二:空指针&野指针
1、空指针:
(1) 没有存储 任何 内存地址 的指针就称为空指针(NULL指针)。
(2) 初始化一个空指针:
    int *ip = NULL;
(3) 校验一个指针是否为一个有效指针时,更倾向于用这种方式
    if(ip != NULL)
2、野指针:
    “野指针”不是NULL指针,是指向"垃圾“内存的指针。
(1)指针变量没有被初始化。任何指针变量刚被创建时不会自动成为NULL指针,他的缺省值是随机的,它会乱指一气。所以指针变量在创建的同时应当被初始化,要么将指针设置为NULL,要么让它指向合法的内存。例如:
    char *p = NULL;
    char *str = (char *)malloc(100); 
(2)指针p被free或者delete之后,没有置为NULL,让人误以为p是个合法的指针。
    (指针定义原理:定义指针,分配内存,指针指向内存)
    free和delete只是把指针所指的内存给释放掉,但并没有把指针本身干掉。free以后其地址仍然不变(非NULL),只是该地址对应的内存是垃圾, p成了”野指针”。如果此时不把p置为NULL,会让人误以为p是个合法的指针。如果程序比较长,我们有时记不住p所指的内存是否已经被释放,在继续使用p之前,通常会用if(p!=NULL)进行放错处理。很遗憾,此时if语句起不到防错作用,因为即便p不是NULL指针,它也不指向合法的内存块。
    char *p = (char *)malloc(100);
    strcpy(p, "hello");
    free(p);    //p所指的内存被释放,但是p所指的地址仍然不变

    if(p!=NULL)    //没有起到放错作用
    {
        strcpy(p, "world");    //出错
    }
(3)指针操作超越了变量的作用范围,这种情况让人防不胜防,示例程序如下:
    class A{
    public:
            void Func(void){cout<<"Func of class A" <<endl;}
    };
    void Test(void){
        A *p;
        {
            A a;
            p = &a;    //注意a的生命周期,只要这个程序块中(花括号里的两行),而不是整个test函数
        }
        p->Func();     //p是“野指针”
    }
 函数Test在执行语句p->Func()时,对象a已经消失,而p是指向a的,所以p就成了”野指针“。
三、void *
    (在C语言里void*是个很有意思的东西)
    含义:  void *可以叫做: 不确定类型的指针 ,void* 可以用来声明指针。如:void *a;
    1、( 不确定类型可以意味) void*可以接受任何类型的赋值            
    void *a = NULL;
    int *b = NULL;
    a = b ;    //a是void* 型指针,任何类型的指针都可以直接赋值给他,无需进行强制类型转换。我们可以认为void是一张白纸,可以在上面写任何类型的数值。 
    2、void *可以赋值给任何类型的变量 但是需要进行强制转换(前提是void *已被指定内存地址):
             int * a = NULL;
            void *b;
            a = (int *)b;

(部分源于网络整理,如有侵权,请联系liujiaqiziv@163.com)

好的,在 C 语言中,“空指针”和“指针”是非常重要的两个概念,它们都涉及到内存管理的问题。 ### 空指针 (Null Pointer) **空指针**是指指向地址值为 `NULL` 的指针变量。它表示该指针当前未指向任何有效的内存位置。 在程序运行时,如果尝试访问或解引用一个空指针,则会触发未定义行为(通常导致程序崩溃)。因此,使用空指针前需要先检查是否为空。 #### 示例: ```c int *p = NULL; // 定义了一个空指针 p if (p == NULL) { printf("Pointer is null.\n"); } ``` --- ### 指针 (Wild Pointer) **指针**是一个指向未知或无效内存区域的指针,其内容未经初始化或者已经释放了所指向的内存空间。由于这种状态的存在,当对指针进行操作时可能会破坏其他数据甚至造成系统不稳定。 常见的形成原因包括: 1. 指针声明之后没有显式地赋初值; 2. 动态分配的空间被 free() 后仍继续使用原指针; 3. 函数返回局部自动变量地址等错误做法; #### 示例: ```c int* p; // 此处 p 未被初始化,成为指针 void func(int **pptr){ int x=5; *pptr=&x; /* 将函数内局部变量取址给外部传入的二级指针 */ } /* 当退出func后,x的生命期结束,再次通过pptr间接访问就会出错 */ int main(){ int y,*q=NULL; func(&q); /* q 变成了指向已销毁堆栈上对象的一个指针*/ if(q != NULL){ cout << "Value:"<< (*q)<<endl ; // 这里存在潜在危险,因为*q不再有效 } } ``` 为了防止这些问题的发生,应该尽量避免上述情况,并养成良好的编码习惯比如及时将不用的动态存储区置零(`free(ptr),ptr=null`) 或者初始化所有的新创建指针等等措施都可以有效地降低产生指针的概率。 --- ### 总结对比: | 特性 | 空指针 | 指针 | |---------------|----------------------------------|-----------------------------| | 是否明确 | 明确无误 | 地址不确定 | | 使用风险 | 如果直接解引会导致异常终止 | 高度不可预测的风险 | 希望这个解释能够帮到您!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值