strtok 如何存储在字符串参数之外?

How could strtok store outside of the string argument?

strtok_s 函数 (C11) 解决的两个问题之一是它防止在输入字符串之外进行存储。据我了解,只有将非空终止字符串传递给 strtok.

才有可能

如果我只将正确的以 null 结尾的字符串传递给 strtok 那么它就没有在输入字符串之外写入的风险是正确的吗?

让我们开始回答主要问题,关于 strtok 写入超出包含字符串的缓冲区的大小。

  1. strtok 实际上修改了输入字符串:它写了一个字符串终止符 ('[=13=]'),其中分隔字符曾经是。通过这种方式,它可以 return 给用户以 null 结尾的令牌
  2. 如果提供了错误输入(缺少字符串终止符的缓冲区),它可能会写入超出输入缓冲区大小的内容。它会读取直到在内存中找到 '[=13=]' 并写入数据,如果在到达末尾之前找到定界符

现在,我们不能正确地说 "strtok_s 防止存储在输入字符串之外" 但我们可以说这个函数提供了一种控制数字的方法被检查的输入字符串的字节数,因此 written(如上所述)。

我们正在谈论的控件与我们使用 strncpy 而不是 strcpy 的控件相同:如果输入字符串避免内存损坏,我们可以将最大大小传递给 strtok_s 如果缺少字符串终止符.

我们来看看strtok_s()签名:

char *strtok_s(char *restrict str, rsize_t *restrict strmax,
               const char *restrict delim, char **restrict ptr);

strtok的接口相比,我们多了两个参数。 ptr 参数对于使其可重入很有用,它也出现在 strtok_r 中。与本题无直接关系

strmax参数就是我们正在寻找的参数

strmax - pointer to an object which initially holds the size of str: strtok_s stores the number of characters that remain to be examined

(重点是我的)

因此,向 strmax 传递指向以包含输入字符串的 char 缓冲区大小初始化的变量的指针,将确保永远不会发生超出该大小的写入。