简体   繁体   English

单个字符的Strlen函数行为

[英]Strlen Function behavior on single character

Here is my code: 这是我的代码:

void func(char c)
{
    char * ptr = &c;
    size_t len = strlen(ptr);
    printf("len - %d\n", len);
}

len is always printed as 1. len始终打印为1。

strlen(..) determines the length of a char array by finding the null character ( \\0 ) at the end of it. strlen(..)通过在结尾处找到空字符( \\0 strlen(..)来确定char数组的长度。 Here ptr is initialized with just the address of a single character ( c ). 这里ptr仅使用单个字符的地址( c )进行初始化。 c does not contain any null characters. c不包含任何空字符。 How does ptr get the length? ptr如何获得长度?

You cannot use strlen() on a pointer that does not point to a null-terminated array. 您不能在不指向以null结尾的数组的指针上使用strlen() It invokes undefined behavior . 它调用未定义的行为

Once your program hits UB, nothing is guaranteed. 一旦你的程序击中UB,没有任何保证。

FWIW, strlen() returns a type size_t , so you should use %zu format specifier to print the result. FWIW, strlen()返回类型size_t ,因此您应该使用%zu格式说明符来打印结果。

The behaviour of your code is undefined on two counts. 代码的行为在两个方面是未定义的 It returns 1 by accident. 它偶然返回1。

  1. strlen works by starting at a given address, and incrementing that address until \\0 is reached. strlen通过从给定地址开始工作,并递增该地址直到达到\\0 This is consistent with how the C standard library models strings. 这与C标准库模拟字符串的方式一致。 If you don't own all the memory (as a contiguous block) between the starting address and that \\0 then the input to strlen is malformed. 如果你没有拥有起始地址和\\0之间的所有内存(作为一个连续的块),则strlen的输入格式不正确。

  2. The behaviour of printf is undefined due to an incorrect format specifier. 由于格式说明符不正确, printf的行为未定义。 Use %zu for size_t . 使用%zu表示size_t

c does not contain any null characters. c不包含任何空字符。 How does ptr get the length? ptr如何获得长度?

It doesn't. 它没有。 It appears to give the correct answer in your tests because the memory location following the address of c happens to contain a zero byte. 它似乎在测试中给出了正确的答案,因为c地址后面的内存位置恰好包含一个零字节。 This location is not defined to contain a zero, nor is the program allowed to access it, so you cannot count on such code continuing to work. 此位置未定义为包含零,程序也不允许访问它,因此您不能指望此类代码继续工作。

In the language of the C standard, the behavior of the program is undefined , which means that not only is the result of the operation unpredictable, the entire program is rendered meaningless. 在C标准的语言中,程序的行为是未定义的 ,这意味着不仅操作的结果不可预测, 整个程序也变得毫无意义。

Even without taking into account undefined behavior, the above code can stop working with the slightest change - for example, when you change architecture, compiler, or even compilation flags, or when you add more functions into the mix. 即使没有考虑未定义的行为,上面的代码也可以停止使用最轻微的更改 - 例如,当您更改体系结构,编译器甚至编译标志时,或者在混合中添加更多功能时。 While such code snippets can be useful to learn how stuff works under the hood, they should never be used in production code. 虽然这些代码片段对于了解内容如何工作非常有用,但它们绝不应该用在生产代码中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM