内存引用错误示例

时间:2017-07-16 04:44:58

标签: c++ c cpu-architecture

typedef struct
{
    int a[2];
    double d;
}struct_t;

double fun(int i)
{
    volatile struct_t s;
    s.d = 3.14;
    s.a[i] = 1073741824;
    return s.d;
}

enter image description here

我在学习有关CSAPP的课程时遇到了这个例子。解释如下所示。但我仍然无法弄明白。 enter image description here

1 个答案:

答案 0 :(得分:2)

让我们看一下你的结构在内存中的样子。假设int是4个字节(因为这是最终行为让我们相信的),这里是:

byte 0,1,2,3: a[0]
byte 4,5,6,7: a[1]
byte 8,9,A,B,C,D,E,F: d

fun(1)创建此结构,将d设置为3.14(0x40091EB851EB851F),然后将a[i]设置为10737418240x40000000)。没有运行时检查以确保a[i]指向a[2]内的位置,这可能会导致问题(如此处所示)。 0和1不会改变任何内容,因为它们将分别写入a[0]a[1]。但是,如果您写信至a[2],则会重叠到d占用的空间。通过写入a[2],您可以替换d的前4个字节。

请注意,您系统上的尺寸可能不同,例如int可能是2个字节,但问题的要点是相同的。

最终,当您到达a[4]时,d会返回到3.14。这是因为你已完全跨过d。超出此点的堆栈是未分配的,因此程序将以分段错误终止。

TL; DR:你写的是与你的双重重叠的记忆。

(注意 - 这是一个不做的例子。这是未定义的行为,并且无法保证在这种情况下给定系统将做什么。)