我有这个功能:
void func(int index, struct foo b[])
{
// ...
a[0][0] = b[index].c[0];
// ...
}
但有时会使用索引-2
调用该函数:
a[0][0] = b[-2].c[0];
我认为-2超出范围,有时会崩溃,但有时却没有。
如果数组b的头地址是0xffd9cda4,那么b [-2]的附加是什么?
0xffd9cda4 + 0xfffffffe = 0x1ffd9cda2? 0x1ffd9cda2有效吗?
它在Linux 64bit上运行。
答案 0 :(得分:2)
您有一个数组b
占用从地址&b[0]
开始的内存块。甚至不要试图找出b[-2]
的地址是什么,因为这显然不在这个数组占用的内存块中。
尝试访问数组边界外的内存会产生未定义的行为。
另请注意,无法在此函数体内检索数组b
的大小:
void func(int index, struct foo b[]) {
// ...
}
答案 1 :(得分:2)
在其边界外访问数组会导致未定义的行为。但是,C没有自动数组边界检查。所以这可能会导致崩溃,但不能保证会崩溃。它通常会溢出到某个恰好位于内存中的对象中。
请注意,如果b
是指针而不是数组,则b[-2]
可能有效。 E.g。
typedef struct foo {
int c[5];
} foo_struct;
foo_struct x[10];
foo_struct *b = &x[3];
如果你现在这样做:
a[0][0] = b[-2].c[0];
它相当于:
a[0][0] = x[1].c[0];
在这种情况下,相关的数组边界是x
。
答案 2 :(得分:0)
b[-2]
与
相同*(b - 2)
这显然是错误的。未定义的行为,访问您不拥有的内存。 UB并不意味着您的程序会崩溃,这意味着程序的行为未定义。