为什么还可以使用数组边界索引?

时间:2014-02-09 07:46:44

标签: c arrays char bounds

char str2[13];
str2[13] = '\0';

请看上面的示例,str2的最大合法索引是12,但在此示例中为13,str2[13] can also work。 这是代码片段:

#include<stdio.h>
int main(){
    char *str1 = "we are happy!";
    char str2[13];
    str2[13] = '\0';
    printf("Before: %s\n", str2);
    char *p = str2;
    while( *str1!='\0' )
        *p++ = *str1++;
    printf("After: %s\n", str2);
}

如何?谁能解释一下呢?

6 个答案:

答案 0 :(得分:1)

访问超出范围的索引会调用未定义的行为。这意味着它可以执行任何操作,包括崩溃程序或使程序崩溃。此外,上面的代码可能会在某些时候崩溃并在其他时间运行。这就是为什么它被称为未定义的行为您的责任永远不会调用未定义的行为。

答案 1 :(得分:1)

您正在访问未分配的内存(通过超出范围),这会调用undefined behavior。您可能会得到预期或意外的输出。什么事情都可能发生。

答案 2 :(得分:1)

C不是内存安全(或托管)语言,允许您访问数组边界之外的内存。它相信你知道自己在做什么,以保持闪电般快速的性能。

答案 3 :(得分:1)

这是str2[13] = '\0';错误的代码。目前很多都没有给任何影响。但是当你使用大型系统时,这个str2[13] = '\0';边界交叉会产生问题。

答案 4 :(得分:0)

您正在写入不属于该阵列的内存。不推荐。

答案 5 :(得分:0)

如果有效,它会偶然发挥作用。它完全取决于变量在堆栈中的组织方式。

如果你运气不好,你的超量计算\0将不再适合字符串,会覆盖堆栈中的重要内容,例如: G。返回地址,这会使你main()在返回时崩溃。

如果您是“半不吉利”,则会在堆栈上覆盖其他内容,例如变量str1。 (您可以在适当的位置验证具有战略性printf("str1 = %p\n", str1);),i。即在做非法的事情之前和之后。

如果你完全幸福,那么你就写一个不重要的地方,因为它是免费的,e。 G。由于堆栈上的对齐问题。

无论在这里有多重要(我认为你在这里“完全开心”),你不能这样做。在更改编译器,编译器选项或其他任何内容时,未定义的行为可以(并最终将)咬你。