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;
}
最佳答案
让我们看看你的结构在内存中是什么样子的。假设 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:您正在写入与您的替身重叠的内存。
(注意 - 这是一个不该做什么的示例。这是未定义的行为,并且不能保证给定系统在这种情况下会做什么。)
关于c++ - 内存引用错误示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45125075/