公司动态

C语言中的野指针和空指针

📅 2026/8/5 9:37:00
C语言中的野指针和空指针
在测试中有时候开机正常有时候跑几分钟死机。测试bug中经常遇到正常跑某个流程是正常的但是在特定条件下总是遇到程序崩溃业务中断。也会遇到同样的代码在这次运行正常下次就会崩溃。今天涉及的空指针就会造成问题现象稳定复现野指针会出现BUG飘忽不定。为了减少这种烦恼本文将介绍什么是空指针和野指针他们有哪些危害平时我们又该如何预防呢一、定义1、空指针NULL Pointer–是合法的指针状态指针变量被赋值为NULL本质是宏一般等价于void*0,代表指针不指向任何合法有效的内存地址明确表明当前指针没有指向有效地址。NULL是C标准规定的特殊常量地址0C新增nullptr2、野指针Wild Pointer指针变量保存了一个随机、未知、不受控制的非法内存地址没有初始化或者指向的内存已经被释放。int*p;//局部变量未初始化内存残留随机值---》野指针int*pmalloc(4);free(p);//free之后不会自动变为NULLp依旧保存原来地址---》野指针二、危害1、空指针带来的困扰1程序直接崩溃确定性故障Linux产生错误SIGSEGVWindows程序闪退。服务端程序一旦崩溃业务中断嵌入式设备直接死机、重启。2崩溃堆栈清晰但是容易忽略边界场景很多场景只是在特定条件下指针才变成NULL正常流程跑不出来。3增加防御代码负担所有接收指针的函数都要加if(pNULL)判断如果漏了就会埋下崩溃隐患。空指针造成的故障稳定只要充分测试大多可以提前发现。2、野指针带来的困扰1Bug难以复现未定义行为UB同样的代码这次运行正常下次崩溃。野指针保存的随机地址每次运行不一样。刚好访问只读内存程序直接崩溃刚好访问进程合法内存静默运行无任何报错。2隐性数据纂改无声的破坏性BUG野指针碰巧指向程序其他变量、数组、栈上数据进行写操作—不会崩溃但是悄悄修改其他变量的值。eg变量值莫名被篡改日志看不出异常业务逻辑错乱计算结果错误。3破坏栈、堆内存引发连锁崩溃egA函数报错根源在完全不相干的B函数野指针。改写堆内存管理块后续调用malloc/free直接崩溃破坏栈上函数返回地址程序跑飞出现诡异的非法指令崩溃–崩溃点不是野指针出错的地方崩溃堆栈完全误导人。4无法通过简单判空防御判空只能防御空指针防御不了野指针。5重复free释放重复free触发堆破坏程序直接崩溃。6嵌入式环境危害大嵌入式没有完善内存保护野指针可能改写寄存器、外设地址导致硬件异常设备失控三、出现后现象表现1、空指针操作现象–不能对空指针引用*pLinux段错误Segmentation faultSIGSEGV程序直接崩溃。Windows触发访问异常程序闪退如下单纯if(pNULL)判断空指针完全没有问题只有解引用才报错。2、野指针操作现象很多人以为出错是空指针实际大量线上崩溃、诡异逻辑错误都是野指针导致有如下几种可能情况直接崩溃访问操作系统保护地址报段错误静默运行没有报错刚好指向程序自己可读内存读写成功潜伏bug破坏其他变量参数改写了别的合法变量的值造成莫名奇妙的数据错乱间歇性崩溃有时候跑正常有时候崩溃。四、野指针产生的根源1、指针未初始化局部指针变量不赋初值栈内存残留随机垃圾值野指针int*p;*p5;//给未知地址赋值了52、内存free后指针没有NULL#includestdio.h#includewindows.h#includemath.hintmain(){SetConsoleOutputCP(65001);SetConsoleCP(65001);int*pmalloc(4);free(p);//p仍然保存原来的地址变为野指针printf(p的地址%p\n,p);if(p!NULL){*p10;//访问已经释放的内存}}3、指针越界、指向临时变量栈内存失效#includestdio.h#includewindows.h#includemath.hint*func(){inta10;returna;}intmain(){SetConsoleOutputCP(65001);SetConsoleCP(65001);int*p;pfunc();printf(p的地址%p\n,p);if(p!NULL){*p10;//访问已经释放的内存}}func中的a是局部变量函数结束栈回收返回的指针变为野指针编译只是警告仍可编译成功五、预防1、编码规范指针一律初始化使用指针之前先确定位置free后置NULL使用指针解引用之前先判断是否为NULL函数接收指针参数优先做空指针防御检查禁止返回局部栈变量的地址2、尽量减少裸指针有条件使用封装3、工具辅助linux:valgrind检测内存泄漏、野指针、重复freegcc编译加警告gcc -wall -wextra尽可能捕获未初始化指针使用地址消毒器AddressSanitizer-fsanitizeaddress快速定位野指针、越界访问。总结空指针明确指向“无地址”可控野指针指向随机未知地址极度危险。