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

检查输入有效性(指针是否为NULL)和检查字符串长度是否为0

检查输入有效性(指针是否为NULL)和检查字符串长度是否为0

这两个检查针对的是完全不同的边界情况,都是必要的防御性编程措施:

1. 空指针检查 if(!src)

  • 目的:防止解引用空指针
  • 场景:当调用者传入 NULL
  • 风险strlen(NULL) 会导致程序崩溃(段错误)
  • 处理:直接返回错误码 -1
  • 必要性:⭐️⭐️⭐️⭐️⭐️(关键安全措施)

2. 空字符串检查 if(len == 0)

  • 目的:处理长度为0的特殊情况
  • 场景:当传入 ""
  • 风险
    1. src + len - 1 会指向 src[-1](非法内存访问)
    2. while(len--) 会执行 len=-1 次(逻辑错误)
  • 处理:直接打印 “(empty)” 并返回
  • 必要性:⭐️⭐️⭐️⭐️(关键逻辑完整性)

为什么两者都需要?

检查类型输入示例不检查的后果修正后行为
空指针检查test_func(NULL)程序崩溃(段错误)返回 -1
空字符串检查test_func("")非法内存访问(未定义行为)打印 “(empty)”

错误路径演示(无空字符串检查)

// 当 src = "" 时:
int len = 0;  // strlen("")=0
const char* s = src + 0 - 1; // = src - 1(非法内存位置!)while(0-- != 0) { // 先判断0!=0→false,但len变为-1// 循环不会执行
}
// 但s已经指向非法位置

实际应用场景

  1. 用户输入处理

    char input[100];
    fgets(input, sizeof(input), stdin);
    test_func(input); // 用户可能直接按回车(空字符串)
    
  2. 网络数据解析

    char* packet = receive_network_data();
    test_func(packet); // 可能收到空包或无效指针
    
  3. API边界防护

    // 库函数必须处理所有可能的输入
    int public_api(char* str) {return test_func(str);
    }
    

完整安全处理流程

int test_func(char* src) {// 第一层:空指针防护(防止崩溃)if(!src) {log_error("NULL pointer passed");return -1;}// 第二层:获取长度int len = strlen(src);// 第三层:空字符串处理(防止逻辑错误)if(len == 0) {printf("(empty)");return 0; // 合法输入,正常返回}// 第四层:内存分配检查char* dest = malloc(len + 1);if(!dest) {log_error("Memory allocation failed");return -2; // 区分内存错误}// ... 后续操作 ...
}

为什么其他语言不需要?

对比其他语言的处理:

语言空指针处理空字符串处理
C/C++需手动检查需手动检查
Java自动抛NullPointerException可正常处理 “”
Python自动抛TypeError可正常处理 “”
Go自动panic可正常处理 “”

在系统级编程中(特别是C/C++),这种显式检查是必要的,因为:

  1. 没有运行时自动检查
  2. 直接内存访问风险高
  3. 未定义行为可能导致严重漏洞

总结

两个检查缺一不可:

  • if(!src) 保护的是程序的生命周期(防崩溃)
  • if(len==0) 保护的是程序的逻辑正确性(防未定义行为)

这正是C语言编程的核心原则:

“永远不要信任外部输入,用防御性代码处理所有边界情况”

http://www.xdnf.cn/news/15244.html

相关文章:

  • 阻有形,容无声——STA 签核之RC Corner
  • 加法器学习
  • docker搭建 与镜像加速器
  • scrapy项目开发流程
  • 【数据结构初阶】--单链表(一)
  • C++ Primer(第5版)- Chapter 7. Classes -001
  • AI大模型(七)Langchain核心模块与实战(二)
  • 嵌入式领域编码合集(为什么中文会乱码)
  • (一)一阶数字低通滤波器---原理及其推导
  • web网站无法抓包排查;burp无法抓包情况
  • 实用技巧 Excel 与 XML互转
  • 鸿蒙进程通信的坑之ServiceExtensionAbility
  • 【大模型】深度学习之神经网络
  • Scrapy爬虫中间件核心技术解析:定制化爬虫的神经中枢
  • 9.2 埃尔米特矩阵和酉矩阵
  • 张量拼接操作
  • Git系列--4.Git分支设计规范
  • 深大计算机游戏开发 实验二
  • 8. JVM类装载的执行过程
  • 【读书笔记】《C++ Software Design》第二章:The Art of Building Abstractions
  • c++反射实现
  • Python ExcelWriter详解:从基础到高级的完整指南
  • 网络安全初级--搭建
  • python的婚纱影楼管理系统
  • Redis Geospatial 功能详解及多边形包含判断实现
  • SpringAI实现聊天记录保存到MySQL
  • 「日拱一码」025 机器学习——评价指标
  • Spring 框架中的设计模式:从实现到思想的深度解析
  • C++类模板继承部分知识及测试代码
  • 在 Android 库模块(AAR)中,BuildConfig 默认不会自动生成 VERSION_CODE 和 VERSION_NAME 字段