繁体   English   中英

C中带有char数组的未定义行为(?)

[英]Undefined behaviour (?) in C with char arrays

当我尝试

    char bla[32] = "foobar";
    int i;
    putchar(bla[i]);

strlen(bla) < i < 32bla[i]始终为\\0 但这实际上不是不确定的行为,应该避免吗?

在C99标准的6.7.8节中,第21段规定:

如果用大括号括起来的列表中的初始化程序少于聚合中的元素或成员,或者用于初始化已知大小的数组的字符串文字中的字符少于该数组中的元素,则聚合的其余部分应与具有静态存储持续时间的对象一样隐式初始化。

第10段指出,静态算术类型(其中包括char)将初始化为零。

基于此,当使用字符串文字作为初始值设定项时,您应该期望将数组的其余部分初始化为零。

C89规范,第8.7节“初始化”:

如果数组的大小固定,则初始化程序的数量不能超过数组成员的数量; 如果较少,则尾随成员将初始化为0。

因此,在您的用法中,尾随的字符用零初始化。

初始化时,C语言遵循全有或全无的原则。 该对象要么完全未初始化,要么完全初始化。 后者意味着,如果您指定的初始化程序少于初始化整个对象所需的初始化程序,则编译器会为您隐式初始化零对象的其余部分。

这适用于所有聚合类型。 在您的情况下,它恰好是用字符串文字初始化的字符数组。 例如,在这种情况下,

int a[100] = { 1 };

您将得到一个由100个int的数组,其中第一个由1初始化,其余设置为0

我认为这是定义明确的行为,实际上是一项功能。 只要您初始化数组或struct中的一个元素,所有其余未明确初始化的元素都将初始化为0

数组未初始化部分的内容取决于它的位置(即,在哪个数据段上)。 如果它在堆栈上,则未初始化的元素是随机值。 通常,如果是全局数组,则初始内容也是不确定的。 如果提供了static规范,编译器将在程序启动时用零初始化其内容。

禁止访问该未初始化的部分,并且不假定未定义的行为,但是结果可能是未定义的。 即使i > sizeof(bla)也不访问bla[i]也是未定义的行为,因为您将拥有随机值或分段错误异常。

它是未定义行为的事实意味着它可以执行任何操作。 每次都可能做同样的事情,但是任何人都在猜测。

那不是编译器的“功能”,而是有据可查的行为。 C编程语言不能保证未初始化变量的值。 因此,您只是在猜测我的价值,并且可以轻松访问不属于您的进程的内存,并且在Windows平台上,例如,这将导致Access Violation异常。 有关更多信息,请参见http://en.wikipedia.org/wiki/Uninitialized_variable

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM