当前位置: 首页 > news >正文

野指针:程序崩溃的隐形杀手

目录

一、概念

二、野指针的成因

1、指针未初始化

2、指针越界访问

3、指针指向已释放的内存

三、如何规避野指针

1、指针初始化

2、防止指针越界

3、指针使用后及时置NULL

4、避免返回局部变量地址

四、总结


一、概念

        野指针(Dangling Pointer)是指指针变量指向的内存位置是不可知随机无效的。这种指针不指向任何合法的内存空间,使用野指针可能导致程序崩溃或不可预测的行为。


二、野指针的成因

1、指针未初始化

        在C语言中,局部指针变量如果不初始化,其值是随机的(垃圾值),直接解引用会导致未定义行为。

#include <stdio.h>
int main()
{ int *p;  // 局部指针变量未初始化,值为随机内存地址*p = 20; // 解引用野指针,可能导致程序崩溃return 0;
}

2、指针越界访问

当指针访问超出其分配的内存范围时,就会变成野指针。

#include <stdio.h>
int main()
{int arr[10] = {0};int *p = &arr[0];for(int i = 0; i <= 11; i++)  // 故意越界访问{*(p++) = i;  // 当i>9时,p成为野指针}return 0;
}

3、指针指向已释放的内存

        当指针指向的内存被释放后,如果没有置空,指针就会变成野指针。现在可以先理解为局部变量被释放了,但是却要返回这个变量。后面学到动态内存管理就会明白。。。。。。

#include <stdio.h>
#include <stdlib.h>int* create_int()
{int *p = (int*)malloc(sizeof(int));*p = 100;free(p);  // 内存释放后,p成为野指针return p; // 返回野指针
}int main()
{int *p = create_int();printf("%d\n", *p);  // 解引用野指针,未定义行为return 0;
}

三、如何规避野指针

1、指针初始化

  • 明确知道指针指向时,直接赋地址值

  • 不确定指针指向时,初始化为NULL

    #ifdef __cplusplus#define NULL 0
    #else#define NULL ((void *)0)
    #endif
    
  • NULL是C语言中定义的一个标识符常量,其值为0。由于0在指针上下文中被视为无效地址,因此对该地址进行读写操作会导致报错。

#include <stdio.h>
int main()
{int num = 10;int *p1 = &num;  // 明确指向int *p2 = NULL;  // 不确定指向时初始化为NULL// 使用前检查if(p1 != NULL) {printf("%d\n", *p1);}return 0;
}

2、防止指针越界

确保指针只在合法范围内使用,特别是数组操作时注意边界检查。

3、指针使用后及时置NULL

        当指针变量指向某块内存区域时,我们可以通过该指针访问该区域。当不再需要使用该指针访问内存时,应将其置为NULL。按照编程惯例,NULL指针不应被访问,同时在使用指针前应当检查其是否为NULL。

        我们可以将野指针比作流浪狗——放任不管的流浪狗相当危险。就像给流浪狗系上绳子能降低风险一样,及时将指针赋值为NULL就相当于把野指针"拴住",从而对其进行有效管理。

        但需注意的是,即使被拴住的狗也应保持距离,不可随意挑逗。同理,在使用指针前,我们必须检查其是否为NULL(即是否为"被拴住的流浪狗")。若指针为NULL则不能直接使用,只有在确认非NULL的情况下才能安全使用。

int main()
{int arr[10] = {1,2,3,4,5,6,7,8,9,10};int *p = &arr[0];for(int i=0; i<10; i++) {*(p++) = i;}// 使用完毕后置NULLp = NULL;// 再次使用前重新赋值并检查p = &arr[0];if(p != NULL) {// 安全操作}return 0;
}

4、避免返回局部变量地址

函数返回后,其栈帧被销毁,局部变量的地址不再有效。

// 错误示例
int* get_local_pointer() 
{int local = 100;return &local;  // 返回局部变量地址
}// 正确做法:返回动态分配的内存或静态变量地址
int* get_valid_pointer()
{static int persistent = 100;  // 静态变量return &persistent;// 或者// int *p = malloc(sizeof(int));// *p = 100;// return p;
}

四、总结

野指针是C/C++程序中常见的安全隐患,通过良好的编程习惯可以有效避免:

  1. 始终初始化指针

  2. 注意指针操作的范围

  3. 及时置空不再使用的指针

  4. 谨慎处理指针的返回和传递

养成这些习惯可以大大减少由野指针引起的内存错误和程序崩溃。

http://www.dtcms.com/a/333756.html

相关文章:

  • 订单状态定时处理(Spring Task 定时任务)
  • 机械学习---词向量转化评价,附代码实例
  • 力扣(接雨水)——单调栈
  • 第454题.四数相加II
  • JavaWeb开发_Day12
  • 基于Selenium的web自动化框架
  • 电视同轴电缆全面指南:从基础到应用,批量测量一键计量
  • 第四章:大模型(LLM)】06.langchain原理-(2)langchain Chain的使用方法
  • 力扣top100(day04-03)--二分查找
  • MqSQL中的《快照读》和《当前读》
  • [论文笔记] WiscKey: Separating Keys from Values in SSD-Conscious Storage
  • Linux core dump
  • Flutter开发 webview_flutter的基本使用
  • MC0423铺砖块
  • Linux系统编程—Linux基础指令
  • OpenCV Python——图像查找(特征匹配 + 单应性矩阵)
  • Linux软件编程(五)(exec 函数族、system、线程)
  • SQL:生成日期序列(填补缺失的日期)
  • 磁悬浮轴承“幽灵振动”克星:深度解析同频振动机理与精准打击策略
  • 优先级反转问题
  • [Python 基础课程]根据描述定义一个 Person 类
  • 关注与优化:用于骨龄评估的交互式关键点定位与颈椎定量分析|文献速递-深度学习人工智能医疗图像
  • Go语言中的指针接收者
  • 语音活动检测VAD技术简介
  • 崩溃大陆2 送修改器 PC/手机双端(Crashlands2)免安装中文版
  • Fanuc机器人EtherCAT通讯配置详解
  • 思科应用中心基础设施(ACI)设计指南
  • Redis面试精讲 Day 22:Redis布隆过滤器应用场景
  • 第2篇_Go语言基础语法_变量常量与数据类型
  • Java-JVM是什么JVM的类加载机制