开发者社区> 流楚丶格念> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

C语言 野指针和空指针

简介: C语言 野指针和空指针
+关注继续查看

空指针


标准定义了NULL指针,它作为一个特殊的指针变量,表示不指向任何东西。要使一个指针为NULL,可以给它赋值一个零值。为了测试一个指针百年来那个是否为NULL,你可以将它与零值进行比较。


对指针解引用操作可以获得它所指向的值。但从定义上看,NULL指针并未指向任何东西,因为对一个NULL指针因引用是一个非法的操作,在解引用之前,必须确保它不是一个NULL指针。


问题思考:


如果对一个NULL指针间接访问会发生什么呢?


结果因编译器而异。


像VS就报错,像DEV这种牛逼的编译器就没事。


案例探索:不允许向NULL和非法地址拷贝内存


不允许向NULL和非法地址拷贝内存:


#include<iostream>
#include<math.h>
#include<string.h>
using namespace std;

void test() {
    char *p = NULL;
    //给p指向的内存区域拷贝内容
    strcpy(p, "1111"); //err

    char *q = (char *)0x1122;
    //给q指向的内存区域拷贝内容
    strcpy(q, "2222"); //err        
}

int main()
{
    test();
    return 0;
}


运行上面的案例就会报错。


image


野指针


在使用指针时,要避免野指针的出现:


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


什么情况下会导致野指针?


指针变量未初始化


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


比如下面代码


void test(){
    int* p = 0x001; //未初始化
    printf("%p\n",p);
    *p = 100;
}


虽然手动给出了地址,但是仍没有指向合法的内存


image


指针释放后未置空


有时指针在free或delete后未赋值 NULL,便会使人以为是合法的。别看free和delete的名字(尤其是delete),它们只是把指针所指的内存给释放掉,但并没有把指针本身干掉。此时指针指向的就是“垃圾”内存。释放后的指针应立即将指针置为NULL,防止产生“野指针”。


指针操作超越变量作用域


不要返回指向栈内存的指针或引用,因为栈内存在函数结束时会被释放。


如何规避野指针


操作野指针是非常危险的操作,应该规避野指针的出现:


初始化时置 NULL


指针变量一定要初始化为NULL,因为任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的。


比如上面的案例,就可以改成:


#include<iostream>
#include<math.h>
#include<string.h>
using namespace std;

void test() {
    int* p = NULL; //初始化
    printf("%p\n", p);

    p = new int;
    *p = 100;
    printf("%p\n", p);
    printf("%d\n", *p);
}
int main()
{
    test();
    return 0;
}


image


释放时 置 NULL


当指针p指向的内存空间释放时,没有设置指针p的值为NULL。delete和free只是把内存空间释放了,但是并没有将指针p的值赋为NULL。通常判断一个指针是否合法,都是使用if语句测试该指针是否为NULL。


例如上面使用完了之后,可以进行下面的操作 释放p 置 NULL。


delete p;
    p = NULL;

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
C语言之数组指针、指针数组
C语言之数组指针、指针数组
27 0
C语言入门——指针入门(一)
C语言入门——指针入门(一)
19 0
Go 语言指针
go语言指针基础 Go 空指针 Go 语言指针数组 Go 语言指向指针的指针 Go 语言指针作为函数参数
11 0
C语言中 指针、引用和取值
  指针是一个存储计算机内存地址的变量。从指针指向的内存读取数据称作指针的取值。指针可以指向某些具体类型的变量地址,例如int、long和double。指针也可以是void类型、NULL指针和未初始化指针。
678 0
C语言——二级指针
二级指针的概念   首先任何值都有地址,一级指针的值虽然是地址,但这个地址做为一个值亦需要空间来存放,是空间就具有地址,这就是存放地址这一值的空间所具有的地址,二级指针就是为了获取这个地址...
690 0
C语言指针5分钟教程
指针、引用和取值 什么是指针?什么是内存地址?什么叫做指针的取值?指针是一个存储计算机内存地址的变量。在这份教程里“引用”表示计算机内存地址。从指针指向的内 存读取数据称作指针的取值。指针可以指向某些具体类型的变量地址,例如int、long和double。
749 0
再谈C语言中数组和指针之间的互操作
再谈C语言中数组和指针之间的互操作 文章来源: 文章作者: 张桂权 发布时间:2006-07-31   字体: [大 中 小]   我曾说过,在C语言中只有一维的数组(这是我对数组的看法),而且数组元素可以是任何类型的数据(或对象),自然也可以是另外的一个数组(因为数组也是一种数据类型)。
508 0
+关注
流楚丶格念
csdn平台优质创作者,51cto TOP博主,360图书馆科技博主,燕山大学目前大三在读,日拱一卒,功不唐捐,加油!!!
1010
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载