我编写了以下代码以更好地理解 strnlen 的行为方式:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
char bufferOnStack[10]={'a','b','c','d','e','f','g','h','i','j'};
char *bufferOnHeap = (char *) malloc(10);
bufferOnHeap[ 0]='a';
bufferOnHeap[ 1]='b';
bufferOnHeap[ 2]='c';
bufferOnHeap[ 3]='d';
bufferOnHeap[ 4]='e';
bufferOnHeap[ 5]='f';
bufferOnHeap[ 6]='g';
bufferOnHeap[ 7]='h';
bufferOnHeap[ 8]='i';
bufferOnHeap[ 9]='j';
int lengthOnStack = strnlen(bufferOnStack,39);
int lengthOnHeap = strnlen(bufferOnHeap, 39);
printf("lengthOnStack = %d\n",lengthOnStack);
printf("lengthOnHeap = %d\n",lengthOnHeap);
return 0;
}
请注意两个缓冲区中故意缺少空终止。 根据文档,长度似乎应该 都是 39 岁:
RETURN VALUE The strnlen() function returns strlen(s), if that is less than maxlen, or maxlen if there is no null terminating ('\0') among the first maxlen characters pointed to by s.
这是我的编译行:
$ gcc ./main_08.c -o main
输出:
$ ./main
lengthOnStack = 10
lengthOnHeap = 10
这是怎么回事?谢谢!
最佳答案
首先,strnlen()
C标准没有定义;这是一个 POSIX 标准函数。
话虽如此,请仔细阅读文档
The
strnlen()
function returns the number of bytes in the string pointed to bys
, excluding the terminating null byte ('\0'), but at mostmaxlen
. In doing this,strnlen()
looks only at the firstmaxlen
bytes ats
and never beyonds+maxlen
.
这意味着,在调用该函数时,您需要确保对于您为 maxlen
提供的值,数组索引对 [maxlen -1]
对于提供的字符串,即 string 中至少有 maxlen
个元素。
否则,在访问 string 时,您将冒险进入未分配给您的内存位置(数组越界访问),从而调用 undefined behaviour .
请记住,此函数用于计算数组的长度,上限为一个值 (maxlen
)。这意味着,提供的数组至少等于或大于边界,而不是相反。
[脚注]:
根据定义,字符串 以 null 结尾。
引用 C11
,章节 §7.1.1,术语定义
A string is a contiguous sequence of characters terminated by and including the first null character. [...]
关于c - 当 strnlen() 的最大长度大于实际缓冲区大小时会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50719026/