strlen是否具有未初始化值的字符串未定义行为?

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); 

是不确定的行为?

调用标准函数strlen会导致未定义的行为。 DR 451澄清了这一点:

当用于不确定的值时,库函数将显示未定义的行为

有关更深入的讨论, 请参阅此主题 。

在这些情况下,您正在显示的变体的行为已明确定义。

  • 未初始化数组的字节具有所有不确定的值,但您设置为0的第10个元素除外。
  • 如果永远不会采用基础对象的地址,或者该值是相应类型的陷阱,则访问不确定的值将仅为UB。
  • 由于这是一个数组,并且通过指针算法访问数组元素,因此第一种情况与此无关。
  • 可以在没有UB的情况下访问任何char值,标准中关于陷阱表示的子句明确地从中排除所有字符类型。
  • 因此,您正在处理的值只是“未指定”。
  • 根据C标准委员会的一些成员每次给出不同的结果,读取未指定的值,有些人称之为“一般”状态左右。 此属性与此属性无关,因为您的函数最多只读取一次这样的值。
  • 因此,您对数组元素的访问可以为您提供任意但有效的char值。
  • 您确定您的for循环最迟在第9位停止,因此您不会超出arrays。

因此,如果您使用特定版本的function,则不会发生超出可见范围的“坏”事情。 但是有一个产生未指定结果的函数调用肯定不是你想在实际代码中看到的。 这样的事情导致了非常微妙的错误,你应该尽一切可能避免它。

不,这不是未定义的行为。 您的strlen函数将在缓冲区结束之前停止。 如果你的strlen函数引用了buffer [10],那么,yes是未定义的。

它肯定会出现意外行为,因为大多数缓冲区都包含随机数据。 “未定义”是人们编写语言标准的特殊词汇。 这意味着任何事情都可能发生,包括内存故障或退出程序。 出乎意料的是,我的意思是确定程序员不想发生什么。 在某些运行中,strlen的结果可能是3或者它可能是10。

是的,这是未定义的行为。 从草案C11标准,§J.2“未定义的行为”:

在以下情况下,行为未定义:

具有自动存储持续时间的对象的值在不确定时使用。