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;
}
答案 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]
设置为1073741824
(0x40000000
)。没有运行时检查以确保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:你写的是与你的双重重叠的记忆。
(注意 - 这是一个不做的例子。这是未定义的行为,并且无法保证在这种情况下给定系统将做什么。)