【问题标题】:Accessing out-of-bounds index with and without optimization在优化和不优化的情况下访问越界索引
【发布时间】:2011-12-08 03:24:14
【问题描述】:

当我运行以下 C 代码时,我会得到不同的输出,具体取决于代码是否在启用优化 (gcc -O) 的情况下运行。

#include <stdio.h>

int main()
{
    int b = 55;
    int a[2] = {4, 5};
    int index;

    printf(" index    a[index]\n ");
    printf("==================\n ");

    for(index = 0; index < 6; index++)
    {
        printf("%2d%12d\n", index, a[index]);
    }

    return 0;
}

我知道在 C 中越界访问索引只会访问从数组更向下的堆栈内存(假设为该索引分配了足够的堆栈空间,否则会出现段错误),因为数组只是 C 中的指针. 但是优化对此有何影响?

【问题讨论】:

  • 您基本上是通过越界读取来读取堆栈。在正常构建中,您将看到 55 被打印(b 的值),但在优化构建中,b 被删除,因此您看不到它。

标签: c optimization


【解决方案1】:

越界访问是未定义的行为。所以编译器可以做它想做的任何事情,任何事情都可以发生。所以尝试“猜测”会发生什么没有多大意义。

在您的情况下,优化可能会影响数组之外的堆栈的顺序和内容。这会给你不同的结果。

【讨论】:

    【解决方案2】:

    您正在导致未定义的行为,简单明了。你真的不能说“为什么这种未定义的行为在这种情况下会导致这个结果,但在另一个情况下会导致不同的结果?”

    如果您想查看哪些指令导致堆栈在优化下有所不同,请使用 objdumpgdb

    编辑:例如,当使用-O 标志编译时,仅在第一个main 开头的堆栈与第一个printf 之前的堆栈有相当多的差异(编译为32 - 为清楚起见):

    未优化:

    0x080483c4 <+0>:    push   ebp
    0x080483c5 <+1>:    mov    ebp,esp
    0x080483c7 <+3>:    and    esp,0xfffffff0
    0x080483ca <+6>:    sub    esp,0x20
    0x080483cd <+9>:    mov    DWORD PTR [esp+0x18],0x37
    0x080483d5 <+17>:   mov    DWORD PTR [esp+0x10],0x4
    0x080483dd <+25>:   mov    DWORD PTR [esp+0x14],0x5
    0x080483e5 <+33>:   mov    eax,0x8048514
    0x080483ea <+38>:   mov    DWORD PTR [esp],eax
    0x080483ed <+41>:   call   0x80482e0 <printf@plt>
    

    优化:

    0x080483c4 <+0>:    push   ebp
    0x080483c5 <+1>:    mov    ebp,esp
    0x080483c7 <+3>:    push   ebx
    0x080483c8 <+4>:    and    esp,0xfffffff0
    0x080483cb <+7>:    sub    esp,0x20
    0x080483ce <+10>:   mov    DWORD PTR [esp+0x18],0x4
    0x080483d6 <+18>:   mov    DWORD PTR [esp+0x1c],0x5
    0x080483de <+26>:   mov    DWORD PTR [esp],0x8048504
    0x080483e5 <+33>:   call   0x80482e0 <printf@plt>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-03
      相关资源
      最近更新 更多