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

C语言面试高频题——strcat、strncat、strcmp、strcpy 哪些函数会导致内存溢出?


1. 函数功能与内存溢出风险

(1) strcat
  • 功能:将源字符串追加到目标字符串的末尾。

  • 原型

    char *strcat(char *dest, const char *src);
    
  • 内存溢出风险

    • strcat 不会检查目标缓冲区的大小,直接将源字符串追加到目标字符串后。
    • 如果目标缓冲区不足以容纳追加的结果,会导致内存溢出。
  • 示例

    char dest[10] = "Hello";
    strcat(dest, " World!"); // 内存溢出:目标缓冲区不足
    
改进方法
  • 使用更安全的函数 strncat,并明确指定最大追加长度。
    strncat(dest, " World!", sizeof(dest) - strlen(dest) - 1);
    

(2) strncat
  • 功能:将源字符串的前 n 个字符追加到目标字符串的末尾。

  • 原型

    char *strncat(char *dest, const char *src, size_t n);
    
  • 内存溢出风险

    • 如果 n 的值过大,仍可能导致目标缓冲区溢出。
    • 需要确保 n 不超过目标缓冲区剩余空间。
  • 示例

    char dest[10] = "Hello";
    strncat(dest, " World!", 10); // 内存溢出:目标缓冲区不足
    
改进方法
  • 手动计算目标缓冲区的剩余空间,避免超出范围。
    strncat(dest, " World!", sizeof(dest) - strlen(dest) - 1);
    

(3) strcmp
  • 功能:比较两个字符串的字典顺序。

  • 原型

    int strcmp(const char *s1, const char *s2);
    
  • 内存溢出风险

    • strcmp 本身不会导致内存溢出,因为它只是逐字符比较两个字符串。
    • 但如果传入的字符串未以 \0 结尾(即非法字符串),可能会引发未定义行为。
  • 改进方法

  • 确保输入字符串是合法的以 \0 结尾的字符串。

    if (strcmp(str1, str2) == 0) {// 字符串相等
    }
    

(4) strcpy
  • 功能:将源字符串复制到目标字符串。

  • 原型

    char *strcpy(char *dest, const char *src);
    
  • 内存溢出风险

    • strcpy 不会检查目标缓冲区的大小,直接将源字符串复制到目标缓冲区。
    • 如果目标缓冲区不足以容纳源字符串,会导致内存溢出。
  • 示例

    char dest[10];
    strcpy(dest, "This is a long string"); // 内存溢出:目标缓冲区不足
    
改进方法
  • 使用更安全的函数 strncpy,并明确指定最大复制长度。
    strncpy(dest, "This is a long string", sizeof(dest) - 1);
    dest[sizeof(dest) - 1] = '\0'; // 确保字符串以 \0 结尾
    

2. 改进总结:如何避免内存溢出?

为了避免上述函数引发的内存溢出问题,可以采取以下措施:

(1) 使用更安全的替代函数
  • strcatstrncat
  • strcpystrncpy
(2) 明确指定缓冲区大小
  • 在调用 strncatstrncpy 时,始终明确指定目标缓冲区的大小。
  • 示例:
    char dest[10];
    strncpy(dest, src, sizeof(dest) - 1);
    dest[sizeof(dest) - 1] = '\0'; // 确保字符串以 \0 结尾
    
(3) 使用现代安全函数
  • 在支持 C11 或更高版本的编译器中,可以使用更安全的函数,如 strlcpystrlcat(需安装扩展库)。
  • 示例:
    strlcpy(dest, src, sizeof(dest)); // 自动截断并确保以 \0 结尾
    strlcat(dest, src, sizeof(dest)); // 自动截断并确保以 \0 结尾
    
(4) 检查输入数据
  • 确保输入字符串是合法的以 \0 结尾的字符串。
  • 对用户输入的数据进行验证和限制。

3. 总结对比

函数功能是否可能导致内存溢出改进方法
strcat追加字符串使用 strncat 并明确指定最大追加长度
strncat追加前 n 个字符是(如果 n 过大)计算目标缓冲区剩余空间,避免超出范围
strcmp比较字符串确保输入字符串以 \0 结尾
strcpy复制字符串使用 strncpy 并明确指定最大复制长度

4. 结论

  • 易导致内存溢出的函数strcatstrcpy
  • 改进方法
    • 使用 strncatstrncpy,并明确指定缓冲区大小。
    • 使用现代安全函数(如 strlcpystrlcat)。
    • 始终确保目标缓冲区足够大,并手动添加 \0 终止符。

相关文章:

  • Android ActivityManagerService(AMS)深度解析
  • 基于javaweb的SpringBoot+MyBatis通讯录管理系统设计与实现(源码+文档+部署讲解)
  • 【维护窗口内最值+单调队列/优先队列】Leetcode 239. 滑动窗口最大值
  • Echarts 问题:自定义的 legend 点击后消失,格式化 legend 的隐藏文本样式
  • PowerShell脚本实现|从文件夹动画序列中均匀选取关键帧(保留首尾帧)
  • redis 数据类型新手练习系列——string类型
  • 【QQMusic项目复习笔记——音乐管理模块详解】第四章
  • Doris vs ClickHouse:深入对比MPP数据库聚合操作的核心区别
  • 重读《人件》Peopleware -(9-1)Ⅱ办公环境Ⅱ“你在这儿从早上9点到下午5点之间什么都做不成.“(上)
  • 2025 年导游证报考条件新政策解读与应对策略
  • 同样机身尺寸下伺服电机比无刷电机扭矩更大的原因
  • LangChain LCEL表达式语言简介
  • IP SSL证书常见问题助您快速实现HTTPS加密
  • ElementUi的tabs样式太难修改,自定义tabs标签页
  • Leetcode 2845 题解
  • Android WindowManagerService(WMS)框架深度解析
  • LibAI Lab闪耀AI出海峰会:技术深耕与全球化增长的双重奏
  • RabbitMQ 复习总结
  • Android 使用支付接口,需要进行的加密逻辑:MD5、HMAC-SHA256以及RSA
  • 实时数据驱动未来:谷云科技CDC实时数据集成平台新版本发布
  • 三大猪企去年净利润同比均较大幅度增长,资产负债率齐降
  • 经济日报金观平:充分发挥增量政策的经济牵引力
  • 推进“即买即退”服务试点,上海静安离境退税商店近400家居全市首位
  • 何立峰出席跨境贸易便利化专项行动部署会并讲话
  • 上海天文馆加持,书友可在徐家汇书院“飞越银河系”!
  • 聚焦“共赢蓝色未来”,首届 “海洋命运共同体”上海论坛举行