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

能否用memchr实现strnlen?该实现是否存在有效性问题?

关于用memchr实现strnlen的疑问解答

当然可以用memchr来实现strnlen,而且你给出的这段实现是完全有效的!我们来逐个拆解你的疑问:

1. memchr的遍历行为

你之前的假设是错的:memchr并不会无条件遍历全部maxlen字节。它的逻辑是从起始地址开始逐个检查字节,一旦找到目标字符(这里就是'\0')就会立刻停止遍历,返回该字符的指针;只有当遍历完前maxlen个字节都没找到目标字符时,才会走完整个范围并返回NULL。

2. strnlen的行为约定

strnlen的核心规则就是:

  • 从str指向的位置开始,最多检查maxlen个字节;
  • 如果在这maxlen字节内找到'\0',返回从str到这个'\0'的偏移量;
  • 如果全程没找到'\0',直接返回maxlen。

它的安全前提是:调用者必须保证str指向的内存区域,前maxlen个字节是可访问的(或者在maxlen范围内存在'\0',此时访问会在终止符处停止)。这和memchr的要求完全匹配,所以用memchr实现是完全符合约定的。

3. 关于无效内存访问的判断

你的这个判断是正确的,但这并不是这个实现的问题——而是strnlen本身的调用前提问题。
不管你是用memchr实现,还是手动写循环遍历,只要调用strnlen时:

  • str指向的内存实际有效大小小于maxlen,且
  • 这段内存里没有'\0'终止符

那么程序都会访问到无效内存区域。这是调用者需要承担的责任:调用strnlen时必须确保maxlen不超过str所在内存的有效长度,或者str在maxlen范围内存在终止符。

再看你的实现代码

这段代码完全符合strnlen的语义:

size_t strnlen(const char *str, size_t maxlen) {
    char *nul = memchr(str, '\0', maxlen);
    return nul ? (size_t)(nul - str) : maxlen;
}

而且还有额外的优势:memchr通常是标准库中经过高度优化的函数(比如用硬件指令批量检查字节),性能往往比手动写的循环更好。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 11:17:30