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