strlen
返回终止空字符前面的字符数。 strlen
的实现可能如下所示:
size_t strlen(const char * str)
{
const char *s;
for (s = str; *s; ++s) {}
return(s - str);
}
此特定实现取消引用s
,其中s
可能包含不确定的值。它等同于:
int a;
int* p = &a;
*p;
例如,如果有人这样做(导致strlen
输出错误):
char buffer[10];
buffer[9] = '\0';
strlen(buffer);
是不确定的行为?
答案 0 :(得分:2)
答案 1 :(得分:2)
在这种情况下,您所展示的变体的行为已明确定义。
0
的第10个元素除外。char
值,标准中关于陷阱表示的子句明确排除了所有字符类型。char
值。for
循环最迟在位置9
处停止,因此您不会超出阵列。所以没有"坏"如果您使用特定版本的功能,可能会发生超出可见范围的事情。但是有一个产生未指定结果的函数调用肯定不是你想在实际代码中看到的。这样的事情导致了非常微妙的错误,你应该尽一切可能避免它。
答案 2 :(得分:1)
不,它不是未定义的行为。您的strlen函数将在缓冲区结束前停止。如果你的strlen函数引用了buffer [10],那么,yes是未定义的。
肯定会出现意外行为,因为大多数缓冲区都包含随机数据。 "未定义"是人们写语言标准的特殊词汇。这意味着任何事情都可能发生,包括内存故障或退出程序。出乎意料的是,我的意思是确定程序员不想发生什么。在某些运行中,strlen的结果可能是3或者可能是10。
答案 3 :(得分:0)
是的,这是未定义的行为。从草案C11标准,§J.2“未定义的行为”:
在以下情况下,行为未定义:
...
使用具有自动存储持续时间的对象的值 不确定的。