【问题标题】:Why the array bounds index can also be used?为什么数组边界索引也可以使用?
【发布时间】:2014-02-09 16:05:08
【问题描述】:
char str2[13];
str2[13] = '\0';

看上面的例子,str2的最大合法索引是12,但是在这个例子中是13,str2[13] can also work。 这是sn-p的代码:

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

怎么样?谁能解释一下?

【问题讨论】:

  • 大多数时候在 C 中,“为什么我可以做我认为不允许的事情”的答案是它没有碰巧在你的脸上炸毁 this时间.
  • 在 Turbo C 中,此代码将起作用。但这是错误的定义方式。 str2[13] = '\0';数组索引仅以 0 到 12 开头。
  • 在 gcc 4.6.3 中,它可以工作。由于这是未定义的行为,它可能会导致程序崩溃或不会导致程序崩溃。发生的情况取决于是否在堆栈上覆盖。

标签: c arrays char bounds


【解决方案1】:

越界访问索引会调用未定义的行为。这意味着它可以做任何事情,包括使您的程序崩溃或使您的程序崩溃。也有可能上面的代码有时会崩溃而有时会工作。这就是为什么它被称为未定义的行为有责任永远不要调用未定义的行为。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

          您正在写入不属于数组的内存。不推荐。

          【讨论】:

          • “不推荐。”比如“不建议谋杀你的邻居”? OP 所做的是未定义的行为 - 这是“严格禁止的”。
          • 更像是修改邻居家的属性。除非您知道自己在做什么,否则不推荐。
          【解决方案6】:

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

          如果你不走运,你的过度计数 \0 不再适合字符串,会覆盖堆栈上的一些重要内容,例如。 G。返回地址,这会使您的main() 在返回时崩溃。

          如果你是“半倒霉”,你会覆盖堆栈上的其他东西,例如变量str1。 (您可以在适当的位置使用战略性printf("str1 = %p\n", str1); 进行验证),i。 e.在做违法的事情之前和之后。

          如果您完全满意,您可以写信到一个不重要的地方,因为它是空闲的,例如。 G。由于堆栈上的对齐问题。

          无论在这里什么重要(我认为你在这里“完全快乐”),你都不能这样做。在更改编译器、编译器选项或其他任何内容时,未定义的行为可能(并且最终会)咬你。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-02-17
            • 2018-04-17
            • 2023-01-08
            • 1970-01-01
            • 2019-11-05
            • 2015-07-01
            相关资源
            最近更新 更多