C 中字符数组的未定义行为(?)

发布于 2024-09-08 01:45:31 字数 217 浏览 3 评论 0原文

当我尝试

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

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

when i try

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

with strlen(bla) < i < 32, bla[i] is always \0. but isn't this in fact undefined behaviour, and should be avoided?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

浅唱々樱花落 2024-09-15 01:45:31

C99 标准第 6.7.8 节第 21 段指出:

如果 a 中的初始值设定项较少
大括号括起来的列表比有
集合的元素或成员,
字符串中的字符或更少
用于初始化数组的文字
已知大小比其中元素的大小
数组的剩余部分
应初始化聚合
与以下对象隐式相同
具有静态存储期限。

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

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

In section 6.7.8 of the C99 Standard, paragraph 21 states:

If there are fewer initializers in a
brace-enclosed list than there are
elements or members of an aggregate,
or fewer characters in a string
literal used to initialize an array of
known size than there are elements in
the array, the remainder of the
aggregate shall be initialized
implicitly the same as objects that
have static storage duration.

And paragraph 10 states that static arithmetic types (which would include char) are initialized to zero.

Based on that, you should expect the rest of the array to be initialized to zero when using a string literal as the initializer.

如果没结果 2024-09-15 01:45:31

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

如果数组有固定大小,
初始化器的数量不能超过
数组成员的数量;如果
后面的成员较少
初始化为 0。

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

C89 spec, section 8.7 "Initialization":

If the array has fixed size, the
number of initializers may not exceed
the number of members of the array; if
there are fewer, the trailing members
are initialized with 0.

So, in your usage, the trailing characters are initialized with zeros.

水水月牙 2024-09-15 01:45:31

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

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

int a[100] = { 1 };

您将获得一个包含 100 个 int 的数组,其中第一个用 1 初始化,其余设置为 0

C language follows the all-or-nothing principle when it comes to initialization. The object is either completely uninitialized or completely initialized. The latter means that if you specify fewer initializers than necessary to initialize the entire object, the rest of the object is implicitly zero-initialized for you by the compiler.

This applies to all aggregate types. In your case it just happens to be a character array initialized with a string literal. In this case, for example,

int a[100] = { 1 };

you get an array of 100 ints with the very first one initialized with 1 and the rest set to 0.

水水月牙 2024-09-15 01:45:31

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

I think this is well defined behavior, actually a feature. As long as you initialize one element in an array or struct all remaining elements that are not explicitly initialized are initialized to 0.

垂暮老矣 2024-09-15 01:45:31

事实上,它是未定义的行为,这意味着它可以做任何事情。它可能每次都会做同样的事情,但所做的事情是任何人的猜测。

The fact that it is undefined behavior means it can do anything. It may do the same anything everytime, but what is done is anyone's guess.

迷爱 2024-09-15 01:45:31

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

That's not a compiler 'feature' but a well documented behavior. The C programming language does not guarantee the value of an uninitialized variable. Therefore you are just guessing what i value is and you can easily access memory which does not belong to your process and on Windows platform, for example, this will lead to Access Violation exception.
See http://en.wikipedia.org/wiki/Uninitialized_variable for more information.

对不⑦ 2024-09-15 01:45:31

数组未初始化部分的内容取决于它所在的位置(即哪个数据段)。如果它在堆栈上,则未初始化的元素是随机值。一般来说,如果是全局范围的数组,初始内容也是未定义的。如果它提供了static 说明符,编译器会在程序启动时用零初始化其内容。

不禁止访问这个未初始化的部分,并且这不会假定未定义的行为,但结果可能是未定义的。如果 i > 则甚至可以访问 bla[i] sizeof(bla) 不是未定义的行为,因为您要么有随机值,要么有分段错误异常。

The contents of uninitialized part of array depends on where it's located (i.e. on which data segment). In case it's on stack, the uninitialized elements are random values. Generally, if it's global-scope array, the initial contents is also undefined. In case it's supplied with static specificator, compiler is initialized its contents with zeroes at program start.

Accessing this uninitialized part is not prohibited and this doesn't assume undefined behaviour, but the result maybe undefined. Even accessing bla[i] if i > sizeof(bla) is not an undefined behavior, since either you'd have random value or segmentation fault exception.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文