C char指针长度

时间:2017-01-12 13:03:39

标签: c arrays initialization strlen

这是Coursera的一个测验(未评分)。问题是,以下代码可能评估的内容是什么?正确的答案是127和0(其他选项崩溃,-1,128。为什么以下代码可能评估为0?我理解为什么它会评估为127.它是否就像char字节未初始化一样简单因此是否可以评估0到127之间的任何#?

int foo(void) {

    char bar[128];

    char *baz = &bar[0];

    baz[127] = 0;

    return strlen(baz);

}

3 个答案:

答案 0 :(得分:5)

代码的行为是 indeterminate 。我的意思是答案可以是0到127之间的任何内容。

strlen将读取未初始化的内存,但不包括bar[127]作为终止条件。

但是因为该数组由char元素组成,所以读取这些数据不是未定义,因为char类型不能有陷阱表示。只是它们包含不确定的值。

(如果bar有静态存储持续时间,那将是完全不同的事情。然后答案总是为零。)

下面的大部分评论都是对这个答案的错误表述作出反应,表明行为未定义。

答案 1 :(得分:5)

以前这个答案有错误的信息,这个案例不会调用undefined behavior

编辑回答:

TL; DR 我们无法得到确定的答案,代码包含不确定行为。

详细说明,char bar[128];是一个自动局部变量,如果没有明确初始化,将包含不确定值。

引用C11,章节§6.7.9

  

如果没有显式初始化具有自动存储持续时间的对象,则其值为   不定。 [....]

在您的代码中,您只为索引127处的数组的一个成员分配了值。剩余的元素仍然具有不确定的值。

尝试将该数组(基本上是指向数组的第一个元素的指针)传递给strlen(),导致读取这些值(搜索空终结符)和由于不确定的值,无法保证它会在任何特定的位置找到空终止符。

  • 它可以在第一个元素中找到空终止符(ASCII值0)并返回0.
  • 它在任何其他数组元素中也找不到任何空终止符(ASCII值0),直到最后一个并返回127.
  • 它可以在数组中的任何位置找到空终止符并返回该计数。

所以,这个问题没有明确答案。

注意: 弥补我的错误理解,以防止读者进一步陷入同一陷阱

这里,读取未初始化的值(即不确定的值)不会调用未定义的行为,正如人们所想的那样。

一个班轮:对象的地址。

有关此主题的详细讨论,请参阅here

答案 2 :(得分:1)

有两件事可以使这个代码UB,如列出的here。这是一个具有自动存储持续时间且具有地址的变量,因此第一种情况肯定不适用。

根据陷阱表示的定义,不允许变量保存陷阱表示C11 6.2.6.1/5强调我的:

  

某些对象表示不需要表示的值   对象类型。如果对象的存储值具有这样的值   表示,并由没有的左值表达式读取   字符类型,行为未定义。如果这样的表示是   由副作用产生,修改对象的全部或任何部分   通过左值表达式,没有字符类型,   行为未定义.50)这种表示称为陷阱   表示。

这意味着该数组包含未指定的值。这种未指定值的一种情况可能是值0,在数组中的任何位置,被视为空终止符。