不能对空指针进行解引用

首先需要知道C中的NULL是什么,它在stdio.h头文件中进行了定义 #define NULL 0,即表示NULL是一个符号常量,代表整数0。

int *p;
p=NULL;

p=NULL,即p是空指针,此时指针变量p指向地址为0的单元,系统保证该单元不作它用(不存放有效数据)。

空指针不会指向任何对象,不应该对空指针进行解引用操作。如果不小心对空指针进行解引用并且对其进行赋值,编译阶段可能会给予通过,但程序运行时会出现错误,甚至让程序崩溃

下面是对空指针进行解引用的错误案例以及解决办法,该代码想要实现使*p等于i的值10(不止一处错误,可以一步一步看):

#include <stdio.h>

void modify_pointer(int *p, int *q) {
    p = q;
}

int main() {
    int *p = NULL;
    int i = 10;
    int *q = &i;
    modify_pointer(p, q);
    printf("after modify_pointer *p=%d\n", *p);
    return 0;
}

上述代码运行结果是:

进程已结束,退出代码为 -1073741819 (0xC0000005)

很明显,代码没有运行成功,原因是经过modify_pointer函数后,指针变量p的值并没有得到改变,程序运行到上面 printf 处崩溃了,因为此时指针变量p仍指向地址为0的单元,而这个单元不存放有效数据,是无法进行访问的,即地址为0的单元是无法进行访问的。

而经过经过modify_pointer函数后,指针变量p的值并没有得到改变的原因是:

C语言中实参变量和形参变量之间的数据传递是单向的‘值传递’方式,指针变量作为函数参数同样也遵循这一规则。

虽不可以通过执行调用函数来改变实参指针变量的值,但可以改变实参指针变量所指变量的值。如果把代码改一下

#include <stdio.h>

void modify_pointer(int *p, int *q) {
    *p = *q; //想将指针变量q所指的变量i的值赋给指针变量p所指内容
}

int main() {
    int *p = NULL;
    int i = 10;
    int *q = &i;
    modify_pointer(p, q);
    printf("after modify_pointer *p=%d\n", *p);
    return 0;
}

但是在此时的运行如下,结果还是不行

进程已结束,退出代码为 -1073741819 (0xC0000005)

此时该程序是运行到函数modify_pointer中的*p = *q语句时崩了(经过调试得知)

原因如下:

void modify_pointer(int *p, int *q) {
    *p = *q; 
}

modify_pointer函数中*p = *q语句,是想将指针变量q所指的变量i的值赋给指针变量p所指内容,但是我们知道指针变量p存放的是符号常量NULL,而且该符号常量NULL内容为0,即p存的地址是0,系统规定该地址0上的单元不存放有效数据,此时你想将指针变量q所指的变量i的值(一个有效数据)放到这里面,程序就崩溃了(为什么地址为0的单元上不能存放有效数据可能涉及更深层的原因,感兴趣的可以搜搜)

如果这样的话就可以了,让指针变量p的初始化值不为NULL:

#include <stdio.h>
#include <stdlib.h>

void modify_pointer(int *p, int *q) {
    *p = *q;
}

int main() {
    int *p;
    p=(int *) malloc(sizeof(int)*4);
    int i = 10;
    int *q = &i;
    modify_pointer(p, q);
    printf("after modify_pointer *p=%d\n", *p);
    free(p); //申请的空间不使用后记得要free一下
    return 0;
}

运行结果为:

after modify_pointer *p=10

也可以利用二级指针,直接改变指针变量p所指向的值,这里面modify_pointer(&p,q)中的&p,是对一级指针取地址,此时&p变成了二级指针(指向指针的指针),

注:二级指针可以看这篇文章呦

#include <stdio.h>

void modify_pointer(int **p, int *q) {
    *p = q;
}

int main() {
    int *p = NULL;
    int i = 10;
    int *q = &i;
    modify_pointer(&p, q);
    printf("after modify_pointer *p=%d\n", *p);
    return 0;
}

运行结果为:

after modify_pointer *p=10

或者C++中的引用:

#include <stdio.h>

void modify_pointer(int *&p, int *q) {
    p = q;
}

int main() {
    int *p = NULL;
    int i = 10;
    int *q = &i;
    modify_pointer(p, q);
    printf("after modify_pointer *p=%d\n", *p);
    return 0;
}

运行结果:

after modify_pointer *p=10

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值