c - 当 strnlen() 的最大长度大于实际缓冲区大小时会发生什么?

标签 c string strlen

我编写了以下代码以更好地理解 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 by s, excluding the terminating null byte ('\0'), but at most maxlen. In doing this, strnlen() looks only at the first maxlen bytes at s and never beyond s+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/

相关文章:

java - 如何在Java中检查字符串数组中的相同名称?

c - 选择在 Linux 上超时之前返回的调用

c - 从c中的文件中读取十六进制值

c - 如何用C语言将二维数组保存到文件中?

c - Linux内核补丁版本宏定义

python字符串拆分切片并放入列表中

java - 是否有用于 Java 字符串的 left() 函数?

c - 计算字符串长度的不同方法

C - strlen ("288_882_288"+strlen ("288_882_288")/2 = 6?

c - 单个字符的 Strlen 函数行为