联合的大小是95个字节,为什么如果我尝试在a处访问102位置,不会引发异常?或者我只是覆盖了另一个内存位置?
#include<stdio.h>
union u{
char a[95];
int b;
char *c;
};
union u u1;
int main()
{
u1.a[102] = 'b';
printf("%c",u1.a[102]);
return 0;
}
答案 0 :(得分:5)
这是未定义的行为。你运气不好,什么也没发生。
答案 1 :(得分:4)
您只是在写一个超出范围的内存位置。 C不关心,但你应该。此外,C没有例外(至少不是你在问题中所说的那种例外)。
答案 2 :(得分:2)
是的,你正在覆盖另一个内存位置。没有什么可能立即发生,但如果在真实程序中完成,您可能会覆盖重要数据,并且程序可能会因此而随时崩溃。不可能说出崩溃将会发生什么,或者发生在何时何地发生。
答案 3 :(得分:1)
当你声明一个联合时,你只是说可以用不同的方式读取x个字节。
union u{
char a[95];
int b;
char *c;
};
这告诉编译器可以将x个字节读取为char数组,整数和char指针。 (另请注意,根据编译器开关,联合可能会用字节填充到偶数个字节)。
union u u1;
当您声明类型为union的变量u1时,您将其声明为全局.data段的成员(请在此处加注)。
现在如果你在联盟说出一个数组之后你会声明一些东西:
char s1[100];
它通常会放在.data段中的u1之后。
因为当您尝试在union实例外部写入(95字节)时,u1的大小为95,所以您可能正在写入s1数组。
+----+ <- 0
| u1 |
+----+ <- 94
| s1 | <- u1.a[102];
+----+
C允许你为了效率而做这些事情,它不对阵列进行范围检查,在某些情况下它是一种祝福 - 它允许很多自由 - 但更多时候它会带来麻烦。在您的情况下,您正在访问内存中可能会或可能不会写保护的某个位置。
答案 4 :(得分:0)
C中没有例外。