单个字符上的Strlen函数行为
这是我的代码:
void func(char c) { char * ptr = &c; size_t len = strlen(ptr); printf("len - %d\n", len); }
len
始终打印为1。
strlen(..)
通过在结尾处找到空字符( \0
strlen(..)
来确定char
数组的长度。 这里ptr
仅使用单个字符的地址( c
)进行初始化。 c
不包含任何空字符。 ptr
如何获得长度?
您不能在不指向以null结尾的数组的指针上使用strlen()
。 它调用未定义的行为 。
一旦你的程序击中UB,没有任何保证。
FWIW, strlen()
返回一个size_t
类型,因此您应该使用%zu
格式说明符来打印结果。
代码的行为在两个方面是未定义的 。 它偶然返回1。
-
strlen
通过从给定地址开始工作,并递增该地址直到达到\0
。 这与C标准库模拟字符串的方式一致。 如果你没有拥有起始地址和\0
之间的所有内存(作为一个连续的块),则strlen
的输入格式不正确。 -
由于格式说明符不正确,
printf
的行为未定义。 将%zu
用于size_t
。
c不包含任何空字符。 ptr如何获得长度?
它没有。 它似乎在测试中给出了正确的答案,因为c
地址后面的内存位置恰好包含一个零字节。 此位置未定义为包含零,程序也不允许访问它,因此您不能指望此类代码继续工作。
在C标准的语言中,程序的行为是未定义的 ,这意味着不仅操作的结果不可预测, 整个程序也变得毫无意义。
即使没有考虑未定义的行为,上面的代码也可以停止使用最轻微的更改 – 例如,当您更改体系结构,编译器甚至编译标志时,或者在混合中添加更多function时。 虽然这些代码片段对于了解内部工作原理是如何有用的,但它们绝不应该用在生产代码中。