You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言中strlen的安全使用:如何处理未终止的char数组避免溢出

结论

  • 标准库strlen完全无法安全处理不带'\0'终止符的char数组,没有任何不额外传参就能安全调用它的方法。因为strlen的实现逻辑就是从传入的指针起始位置向后遍历直到遇到'\0'为止,若输入没有终止符,必然会越界访问数组外的内存,引发未定义行为。
  • 唯一通用的修复方案就是你提到的,修改函数签名新增长度上限参数,结合安全的长度计算函数使用。

具体实现方案

方案1:使用标准库strnlen

strnlen是POSIX.1-2008、C11标准正式纳入的字符串处理函数,专门针对不知道输入是否带终止符的场景,函数原型为:

size_t strnlen(const char *s, size_t maxlen);

它最多只会扫描前maxlen个字节:如果在范围内找到'\0'就返回实际字符串长度,找不到就直接返回maxlen,不会越界访问内存。
修改后的代码如下:

void foo(char *c, size_t MAXSIZE) {
    size_t a = strnlen(c, MAXSIZE);
    // 后续处理:如果a等于MAXSIZE,说明输入不是合法C字符串,需要单独处理,不能直接传入strcpy、printf("%s")等要求合法字符串的函数
}

方案2:兼容旧环境自行实现安全求长逻辑

如果你的开发环境不支持strnlen,可以自己实现等价逻辑,代码参考:

size_t safe_strlen(const char *s, size_t maxlen) {
    if (s == NULL || maxlen == 0) return 0;
    size_t len = 0;
    while (len < maxlen && s[len] != '\0') {
        len++;
    }
    return len;
}

补充说明

C语言的裸字符指针本身不携带任何关联数组的长度信息,没有任何通用方法可以在仅拿到指针的前提下,判断指针指向内存的有效范围,也无法确定后续内存中出现的'\0'是不是属于当前数组的终止符。因此必须由调用方传入数组的长度上限,没有其他绕路的办法。


内容的提问来源于stack exchange,提问作者Klinda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 22:36:01