这是我的代码:
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
如何获得长度?
答案 0 :(得分:7)
您不能在不指向以null结尾的数组的指针上使用strlen()
。它调用undefined behavior。
一旦你的程序击中UB,就没有任何保证。
FWIW,strlen()
返回类型size_t
,因此您应该使用%zu
格式说明符来打印结果。
答案 1 :(得分:4)
您的代码的行为在两个方面是 undefined 。它偶然返回1.
strlen
通过从给定地址开始,并递增该地址直到达到\0
为止。这与C标准库模拟字符串的方式一致。如果您不拥有起始地址与\0
之间的所有内存(作为连续块),则strlen
的输入格式不正确。
由于格式说明符不正确,printf
的行为未定义。将%zu
用于size_t
。
答案 2 :(得分:0)
c不包含任何空字符。 ptr如何获得长度?
没有。它似乎在您的测试中给出了正确的答案,因为c
地址后面的内存位置恰好包含零字节。此位置未定义为包含零,程序也不允许访问它,因此您不能指望此类代码继续工作。
在C标准的语言中,程序的行为是 undefined ,这意味着不仅操作的结果不可预测,the entire program is rendered meaningless.
即使没有考虑未定义的行为,上述代码也可以停止使用最轻微的更改 - 例如,当您更改体系结构,编译器甚至编译标志时,或者在混合中添加更多功能时。虽然这些代码片段对于了解内容如何工作非常有用,但它们绝不应该用在生产代码中。