【问题标题】:Memory handling in x64 vs x86 - C languagex64 与 x86 中的内存处理 - C 语言
【发布时间】:2018-10-30 18:49:07
【问题描述】:

当我在 X64 计算机上使用 GCC 编译器运行下面的代码时,i 的输出为 90,但在 x86 上运行时它的值仍然为 2,那么处理内存的区别在哪里?

#include <stdio.h>

int main(void)
{
  int arr[3]={50,7,30};
  int i=2;

  arr[3]=90;     
  printf("arr[2]=%d,arr[3]=%d,i=%d", arr[2], arr[3], i);

  return 0;
}

【问题讨论】:

  • 没有arr[3]。它超出了范围。
  • arr[3]=90; 写入超出数组范围 --> 未定义行为
  • 当你编译 x64 时,在编译行添加-O3...我敢打赌你会感到惊讶。
  • @AlexLop。哪个编译行!?

标签: c memory x86 64-bit x86-64


【解决方案1】:

C 中的数组索引从 0 开始,因此 arr 的有效索引是 0、1 和 2。使用 arr[3] 正在注销数组的末尾。这样做会调用undefined behavior,在您的情况下,这表现为 x86 和 x64 上的不同行为。如果使用不同的编译器或更改优化设置,您可能还会得到不同的行为。

关于这种特定行为,您似乎认为i 应该立即出现在内存中的arr 之后,以便写入arr[3] 实际上写入i。但是,不能保证范围内局部变量的顺序。这不仅仅是 x86 / x64 的事情。

不要读/写超出数组的末尾,你不会看到这些类型的问题。

【讨论】:

    【解决方案2】:

    就像其他人解释的那样,超出数组范围的写入是 UB。

    我想指出一些您可能没有意识到的其他事情: 从您的问题看来,您希望访问 arr[3] 会覆盖您的 i 变量。

    即使编译器会按照它们在源代码中出现的顺序分配您的局部变量(这根本无法保证!),您也不会覆盖 i

    这样做的原因是通常堆栈向下增长。因此,如果编译器遵循您在堆栈上的分配顺序,i 将获得代码中的最低地址。

    但为了允许正常的指针运算(使用 [] 数组表示法时会发生这种情况),增加 arr 的索引将在堆栈中向上,并且您将覆盖函数的激活记录。非常糟糕。

    试试这个版本的代码(在 GCC 中使用 -fstack-protector-all 编译):

    #include <stdio.h>
    
    void smash(void){
       int arr[3] = {50, 7, 30};
       int i = 2;
    
       arr[3] = 90;
    
       //Let's look at the addresses
       printf("&i = %p, &arr[0] = %p, , &arr[3] = %p\n", &i, &arr[0], &arr[3]);
    
       printf("arr[2] = %d, arr[3] = %d, i = %d\n", arr[2], arr[3], i);
    
       int i2 = 3;
       //Small loop limit can trigger stack protector *upon* return from smash()
       //Large loop limit will create a segfault *before* returning from smash()
       for(; i2 < 10; i2++)
          arr[i2] = 99999;
    
       //Just to see where we crash.
       printf("%d\n", i2);
    }
    
    int main(void)
    {
       smash();
       return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-21
      • 2022-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多